假设我有以下课程:
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;
}
}
然后,我在Foo
中有几个Collection<Foo> fooCollection
个对象和字符串数组String[] names
。
现在,我想按属性fooCollection
订购name
,name
中订购names
字符串的顺序相同。
如何使用Java 8 Stream做到这一点?
答案 0 :(得分:4)
您可以使用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())));
或者如果你一定想要Stream API:
List<Foo> fooList = fooCollection.stream()
.sorted(Comparator.comparingInt(f -> nameList.indexOf(f.getName())))
.collect(Collectors.toList());
但是如果你有很多名字,你可以考虑提高效率,首先准备一个反向的名字索引:
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());
这里我假设所有名称都不同,每个Foo
在names
数组中都有相应的名称。
答案 1 :(得分:0)
首先,您使用static factory methods从Comparator
数组构建names
,例如通过数组上的reduction。然后将比较器传递给stream.sort
答案 2 :(得分:0)
首先,您需要将String[]
转换为List<String>
才能利用indexOf
方法。然后使用Foo.name
接口比较新名称List中Comparator<T>
的等效索引。我制作了整个代码,以便您可以复制并运行它:
package io.github.gabrielbb.java.utilities;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
*
* @author Gabriel Basilio Brito
* @since 27-12-16
*/
public class CollectionSortingBasedOnArray {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
personList.add(new Person("Donald", "Trump"));
personList.add(new Person("Gabriel", "Basilio"));
personList.add(new Person("Chris", "Brown"));
personList.add(new Person("Barack", "Obama"));
String[] sortedNames = {"Barack", "Chris", "Donald", "Gabriel"};
List<String> sortedNamesList = Arrays.asList(sortedNames); // Converting Array to List to take advantage of "indexOf" method
Collections.sort(personList, (Person p1, Person p2) -> { // Using the Comparator<T> interface with Lambda Expression
Integer n1 = sortedNamesList.indexOf(p1.getName()); // Get the position of the first person name in the Names List (before an Array)
Integer n2 = sortedNamesList.indexOf(p2.getName()); // Get the position of the second person name in the Names List
return n1.compareTo(n2); // Now is simple: Just compare those indexes.
});
// Collections.sort lines can be replaced with: personList.sort(Comparator.comparingInt(p -> sortedNamesList.indexOf(p.getName())));
personList.stream().forEach((p) -> {
System.out.println(p.getName() + " " + p.getLastName()); // Print each Person Information
});
}
}
class Person {
private String name;
private String lastName;
public Person(String name, String lastName) {
this.name = name;
this.lastName = lastName;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the lastName
*/
public String getLastName() {
return lastName;
}
/**
* @param lastName the lastName to set
*/
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
Collections.sort行是为了更好地理解背后发生的事情,但它可以替换为:
personList.sort(Comparator.comparingInt(p -> sortedNamesList.indexOf(p.getName())));
答案 3 :(得分:-1)
已经有一段时间了,但你可以像这样缩短比较
List fooSortedByName = new ArrayList(fooCollection);
fooSortedByName.sort(Comparator.comparing(Foo::getName));