Java收集到列表,但指定预定义的前两个元素顺序

Java收集到列表,但指定预定义的前两个元素顺序,java,java-8,java-stream,comparator,Java,Java 8,Java Stream,Comparator,我有一个列表对象。从中我想得到一个所有id的列表,我总是希望id“abc”和“bob”作为列表的第0个和第1个索引(如果可用)。有没有一种方法可以通过java流实现这一点 class Person { private String id; } List<Person> allPeople = ... List<String> allIds = allPeople.stream().map(Person::id).collect(Collectors.toList(

我有一个
列表
对象。从中我想得到一个所有id的列表,我总是希望id“abc”和“bob”作为列表的第0个和第1个索引(如果可用)。有没有一种方法可以通过java流实现这一点

class Person {
   private String id;
}

List<Person> allPeople = ...
List<String> allIds = allPeople.stream().map(Person::id).collect(Collectors.toList());
班级人员{
私有字符串id;
}
列出所有人=。。。
List allIds=allPeople.stream().map(Person::id).collect(Collectors.toList());
我的做法是:

Set<String> allIds = allPeople.stream().map(Person::id).collect(Collectors.Set());
List<String> orderedIds = new ArrayList<>();
if(allIds.contains("abc")) {
   orderedIds.add("abc");
}
if(allIds.contains("bob")) {
   orderedIds.add("bob");
}
//Iterate through the set and all add all entries which are not bob and abc in the list.
Set allIds=allPeople.stream().map(Person::id).collect(Collectors.Set());
List orderedIds=new ArrayList();
如果(所有标识包含(“abc”)){
orderedds.add(“abc”);
}
if(allid.contains(“bob”)){
orderedds.add(“bob”);
}
//遍历集合并添加列表中不是bob和abc的所有条目。

如果要在“完全”流管道中执行此操作,可以执行以下操作:

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”,那就换个名字

map.get(true).stream()


您可以做的另一个解决方案是:

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());

我假设每个id在列表中只出现一次。因此,我会选择一个简单明了的解决方案:

List<Person> allPeople = ...;
List<String> allIds = allPeople.stream().map(Person::id).collect(toCollection(ArrayList::new));
boolean foundBob = allIds.remove("bob");
if (foundBob) allIds.add(0, "bob");
boolean foundAbc = allIds.remove("abc");
if (foundAbc) allIds.add(0, "abc");
这样,您的代码更简单、更容易理解:

List<Person> allPeople = ...;
List<String> allIds = allPeople.stream().map(Person::id).collect(toCollection(ArrayList::new));
moveToHead(allIds, "bob");
moveToHead(allIds, "abc");
列出所有人=。。。;
List allid=allPeople.stream().map(Person::id).collect(toCollection(ArrayList::new));
moveToHead(allIds,bob);
moveToHead(allIds,abc);

在这里,您似乎需要更多的
优先队列
而不是
列表
,因此可能是这样的:

PriorityQueue<String> pq = list.stream()
            .map(Person::getId)
            .distinct()
            .collect(Collectors.toCollection(() -> new PriorityQueue<>(
                    Comparator.comparing(x -> !"abc".equals(x))
                            .thenComparing(x -> !"bob".equals(x)))));

受Stuart Marks启发,有一个更简单的解决方案:

List<String> allIds = allPeople.stream()
      .map(Person::getId)
      .distinct()
      .sorted(comparing(x -> !"abc".equals(x)).thenComparing(x -> !"bob".equals(x)))
      .collect(Collectors.toList());
List allid=allPeople.stream()
.map(Person::getId)
.distinct()
.排序(比较(x->!“abc.”等于(x))。然后比较(x->!“bob.”等于(x)))
.collect(Collectors.toList());

Sweet。那很有趣。abc在Bob之前的保证是什么?@user1692342如果您使用第一种方法并使用提供的比较器,那么“abc”将始终在“Bob”之前,而第二种方法将实现同样的效果。非常好!我想您可以在List.sort()或Stream.sorted()中使用这个比较器。实际上是一个类似的比较器,它使用相同的技术比较Person对象。@StuartMarks是的,我不知道为什么我从一个
PriorityQueue
开始。谢谢,您应该使用
来收集(ArrayList::new)
,因为
toList()
不能保证返回可变的
列表。
List<Person> allPeople = ...;
List<String> allIds = allPeople.stream().map(Person::id).collect(toCollection(ArrayList::new));
moveToHead(allIds, "bob");
moveToHead(allIds, "abc");
PriorityQueue<String> pq = list.stream()
            .map(Person::getId)
            .distinct()
            .collect(Collectors.toCollection(() -> new PriorityQueue<>(
                    Comparator.comparing(x -> !"abc".equals(x))
                            .thenComparing(x -> !"bob".equals(x)))));
List<String> result = new ArrayList<>();
while (!pq.isEmpty()) {
   result.add(pq.poll());
}
List<String> allIds = allPeople.stream()
      .map(Person::getId)
      .distinct()
      .sorted(comparing(x -> !"abc".equals(x)).thenComparing(x -> !"bob".equals(x)))
      .collect(Collectors.toList());