Java 8 - 按在数组中定义的顺序的属性对对象集合进行排序

Yan*_*off 2 sorting java-8 java-stream

假设我有以下课程:

public class Foo {
    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public Foo setId(int id) {
        this.id = id;
        return this;
    }

    public String getName() {
        return name;
    }

    public Foo setName(String name) {
        this.name = name;
        return this;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,我有几个Foo对象Collection<Foo> fooCollection和 String Array String[] names

现在我想fooCollection按属性name排序,与name字符串排序的顺序相同names

我如何使用 Java 8 Stream 做到这一点?

Tag*_*eev 6

您可以Arrays.asList(names).indexOf(f.getName())用作比较键:

List<String> nameList = Arrays.asList(names);
List<Foo> fooList = new ArrayList<>(fooCollection);
fooList.sort(Comparator.comparingInt(f -> nameList.indexOf(f.getName())));
Run Code Online (Sandbox Code Playgroud)

或者,如果您确实想要 Stream API:

List<Foo> fooList = fooCollection.stream()
    .sorted(Comparator.comparingInt(f -> nameList.indexOf(f.getName())))
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

但是,如果您有很多名称,您可以考虑提高效率,首先准备名称的反向索引:

Map<String, Integer> nameMap = IntStream.range(0, names.length)
    .boxed()
    .collect(Collectors.toMap(idx -> names[idx], Function.identity()));
List<Foo> fooList = fooCollection.stream()
    .sorted(Comparator.comparing(f -> nameMap.get(f.getName())))
    .collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

这里我假设所有的名字都不同,每个Foo名字在names数组中都有对应的名字。