OrderEntry Object:
@Data
public static class OrderEntry {
private String entryNumber;
// giftFlag=0 means the orderEntry is a normal entry
// giftFlag=1 means the orderEntry is a gift entry
private Integer giftFlag;
private List<String> sourceEntryNumbers;
}
giftFlag=0 means the orderEntry is a normal entry
giftFlag=1 means the orderEntry is a gift entry
I have a list of orderEntry, it contains normal entry and gift entry. Now I want to sort the orderEntry list with specified order, normal entry firstly, if this normal entry have gift entry, then gift entry secondly.
update: What I want to sort is ordering the non-gift by entryNumber and tailing the gifts.
It's not the multiple fields sort and can not use Comparator's compare
and thenComparing
methods
How to sort this list? Any help?
@Test
public void testSort() {
OrderEntry orderEntry1 = new OrderEntry();
orderEntry1.setEntryNumber("1");
orderEntry1.setGiftFlag(0);
OrderEntry orderEntry2 = new OrderEntry();
orderEntry2.setEntryNumber("2");
orderEntry2.setGiftFlag(0);
OrderEntry orderEntry3 = new OrderEntry();
orderEntry3.setGiftFlag(1);
// it means this gift orderEntry created from orderEntry1 and orderEntry2
orderEntry3.setSourceEntryNumbers(Arrays.asList("1", "2"));
OrderEntry orderEntry4 = new OrderEntry();
orderEntry4.setEntryNumber("3");
orderEntry4.setGiftFlag(0);
OrderEntry orderEntry5 = new OrderEntry();
orderEntry5.setGiftFlag(1);
// it means this gift orderEntry created from orderEntry3
orderEntry5.setSourceEntryNumbers(Arrays.asList("3"));
OrderEntry orderEntry6 = new OrderEntry();
orderEntry6.setEntryNumber("4");
orderEntry6.setGiftFlag(0);
OrderEntry orderEntry7 = new OrderEntry();
orderEntry7.setGiftFlag(1);
// it means this gift orderEntry created from orderEntry3
orderEntry7.setSourceEntryNumbers(Arrays.asList("4"));
OrderEntry orderEntry8 = new OrderEntry();
orderEntry8.setEntryNumber("8");
orderEntry8.setGiftFlag(0);
List<OrderEntry> list = new ArrayList<>();
list.add(orderEntry1);
list.add(orderEntry2);
list.add(orderEntry4);
list.add(orderEntry6);
list.add(orderEntry3);
list.add(orderEntry5);
list.add(orderEntry7);
list.add(orderEntry8);
System.out.println(JSON.toJSONString(list));
// output:
// [{"entryNumber":"1","giftFlag":0},{"entryNumber":"2","giftFlag":0},{"entryNumber":"3","giftFlag":0},{"entryNumber":"4","giftFlag":0},{"giftFlag":1,"sourceEntryNumbers":["1","2"]},{"giftFlag":1,"sourceEntryNumbers":["3"]},{"giftFlag":1,"sourceEntryNumbers":["4"]},{"entryNumber":"8","giftFlag":0}]
// expected output:
// [{"entryNumber":"1","giftFlag":0},{"entryNumber":"2","giftFlag":0},{"giftFlag":1,"sourceEntryNumbers":["1","2"]},{"entryNumber":"3","giftFlag":0},{"giftFlag":1,"sourceEntryNumbers":["3"]},{"entryNumber":"4","giftFlag":0},{"giftFlag":1,"sourceEntryNumbers":["4"]},{"entryNumber":"8","giftFlag":0}]
}
If I understood you correctly, you want the gift orders
to follow the highest normal orders
they reference.
Then we can add a method to either return the entryNumber or the last sourceEntry and use this in the compareTo method. Also we need to sort then by the giftFlag, because we want entryNumber "2" to come before the sourceEntryNumbers List.of("1", "2).
@Data
public class OrderEntry implements Comparable<OrderEntry>{
private String entryNumber;
// giftFlag=0 means the orderEntry is a normal entry
// giftFlag=1 means the orderEntry is a gift entry
private Integer giftFlag;
private List<String> sourceEntryNumbers;
// can be omitted, it you know that the sourceEntryNumbers are sorted already
public void setSourceEntryNumbers(List<String> sourceEntryNumbers) {
this.sourceEntryNumbers = sourceEntryNumbers.stream().sorted().toList();
}
private String getEntryNumberForSorting() {
if (entryNumber != null)
//if (giftFlag == 1) // alternatively
{
return entryNumber;
}
//return sourceEntryNumbers.getLast(); // since java 21
return sourceEntryNumbers.get(sourceEntryNumbers.size() - 1);
}
@Override
public int compareTo(OrderEntry o) {
return Comparator.comparing(OrderEntry::getEntryNumberForSorting)
.thenComparing(OrderEntry::getGiftFlag)
.compare(this, o);
}
}
and then you can sort them e.g. like
final var orderedOrders = orders.stream()
.sorted()
.toList();