если вы хотите выполнить это в «полностью» потоковом конвейере, вы можете сделать:
allPeople.stream()
.map(Person::id)
.distinct()
.collect(collectingAndThen(partitioningBy(s -> "abc".equals(s) || "bob".equals(s)),
map -> Stream.concat(map.get(true).stream(), map.get(false).stream())));
.collect(toList());
, если вы всегда хотите, чтобы «abc» был перед «bob», тогда измените
map.get(true).stream()
до
map.get(true).stream()
.sorted(Comparator.comparing((String s) -> !s.equals("abc")))
Другое решение, которое вы могли бы сделать, это:
Set<String> allIds = allPeople.stream().map(Person::id).collect(toSet());
List<String> orderedIds = Stream.concat(allIds.stream()
.filter(s -> "abc".equals(s) || "bob".equals(s))
.sorted(Comparator.comparing((String s) -> !s.equals("abc"))),
allIds.stream().filter(s -> !"abc".equals(s) && !"bob".equals(s)))
.collect(toList());
, которое в значительной степени делает то же самое, что и выше partitioningBy
, но только вдругой подход.
Наконец, вы можете быть удивлены, но ваш подход на самом деле кажется хорошим, поэтому вы можете дополнить его:
Set<String> allIds = allPeople.stream().map(Person::id).collect(toSet());
List<String> orderedIds = new ArrayList<>();
if(allIds.contains("abc"))
orderedIds.add("abc");
if(allIds.contains("bob"))
orderedIds.add("bob");
orderedIds.addAll(allIds.stream().filter(s -> !"abc".equals(s) && ! "bob".equals(s)).collect(toList()));