Reputation: 811
Let's say, I have a list:
unordered_list = ['c-1','a-2','a-4','b-2','a-1','b-3','c-3','c-4']
And I've got some conditions:
Result should look like:
ordered_list = ['b-3','c-3','a-1','a-2','a-4','b-2','c-1','c-4']
I've spent much time to find some efficient way to realize it in Groovy, but didn't succeed, since I'm beginner in it. Any tips will be much appreciated. Thanks in advance!
Upvotes: 0
Views: 434
Reputation: 4789
No need for all the other lists, you can stream an array directly
Stream.concat(Stream.of(unordered_list)
.filter(s -> s.endsWith("3"))
.sorted(),
Stream.of(unordered_list))
.filter(s -> !s.endsWith("3"))
.sorted()
.collect(toList());
Or for actual List:
List<String> unorderedList = asList("c-1", "a-2", "a-4", "b-2", "a-1", "b-3", "c-3", "c-4");
Stream.concat(unorderedList.stream()
.filter(s -> s.endsWith("3"))
.sorted(),
unorderedList.stream()
.filter(s1 -> !s1.endsWith("3"))
.sorted())
.collect(toList());
And finally, another way using a partition
Map<Boolean, List<String>> endsWith3Partition = Stream.of(unordered_list)
.sorted()
.collect(partitioningBy(s -> s.endsWith("3")));
List<String> sorted = new ArrayList<>(unordered.length);
sorted.addAll(endsWith3Partition.get(true));
sorted.addAll(endsWith3Partition.get(false));
Upvotes: 2
Reputation: 30819
You can do it by using Java 8's stream
, e.g.:
List<String> list = Arrays.asList(new String[]{"c-1","a-2","a-4","b-2","a-1","b-3","c-3","c-4"});
TreeMap<Boolean, List<String>> lists = list.stream()
.collect(Collectors.groupingBy(s -> s.toString().endsWith("3"), TreeMap::new, Collectors.toList()));
final List<String> result = new ArrayList<>();
lists.descendingMap().forEach((k, v) -> {
Collections.sort(v);
result.addAll(v);
});
System.out.println(result);
Upvotes: 1
Reputation: 476659
You can write a comparator, like the one below:
Arrays.sort(unordered_list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
String[] o1s = o1.split('-');
String[] o2s = o2.split('-');
boolean end1_3 = o1s[1].equals("3");
boolean end2_3 = o2s[1].equals("3");
if(end1_3 && end2_3) {
return 0; //both end with 3
} else if(end1_3) {
return -1; //only the first ends with 3, so less than
} else if(end2_3) {
return 1; //only the second ends with 3, so greater than
}
if(!o1s[0].equals(o2s[0])) { // first group not same
return o1s[0].compareTo(o2s[0]); // compare first groups
}
return o1s[1].compareTo(o2s[1]); // assume equal
}
});
Upvotes: 2