Sorting Java 8-按数组中定义的顺序按属性对对象集合排序
假设我有以下课程:Sorting Java 8-按数组中定义的顺序按属性对对象集合排序,sorting,java-8,java-stream,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() { retur
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;
}
}
然后,在Collection fooCollection
中有两个Foo
对象和字符串数组String[]names
现在我想按属性name
对fooCollection
进行排序,name
字符串的排序顺序与names
相同
如何使用Java 8 Stream实现这一点?首先,您可以使用从
名称数组构建一个比较器,例如通过数组上方的。然后将比较器传递给stream.sort
您可以使用数组.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())));
List-nameList=Arrays.asList(名称);
列表列表=新的ArrayList(fooCollection);
sort(Comparator.comparingit(f->nameList.indexOf(f.getName()));
或者,如果您确实想要流API:
List<Foo> fooList = fooCollection.stream()
.sorted(Comparator.comparingInt(f -> nameList.indexOf(f.getName())))
.collect(Collectors.toList());
List-doulist=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());
Map nameMap=IntStream.range(0,names.length)
.boxed()
.collect(Collectors.toMap(idx->names[idx],Function.identity());
List-doulist=fooCollection.stream()
.sorted(Comparator.comparing(f->nameMap.get(f.getName()))
.collect(Collectors.toList());
这里我假设所有的名称都不同,并且每个Foo
在names
数组中都有相应的名称。首先需要将字符串[]
转换为列表
,以利用indexOf
方法。然后使用Comparator
界面比较新名称列表中Foo.name
的等效索引。我制作了整个代码,因此您可以复制并运行它:
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;
}
}
已经有一段时间了,但是你可以像这样缩短比较
List fooSortedByName = new ArrayList(fooCollection);
fooSortedByName.sort(Comparator.comparing(Foo::getName));
你能给出一个比较器的代码示例吗?不知道怎么办it@YanickNedderhoff检查我发布的代码中的注释这如何涉及名称
数组?谢谢,我认为它的流api版本正好解决了我的问题!我认为这个答案不能回答人们的问题。请求是按照names
中的名称顺序对fooCollection
进行排序。没错,List.copyOf()返回一个不可变列表,我将其更改为使用ArrayList,现在它基本上是acceptedx答案;-)不是。接受的答案按与fooCollection
分开的名称列表进行排序。您只需按名称字段进行排序。
List fooSortedByName = new ArrayList(fooCollection);
fooSortedByName.sort(Comparator.comparing(Foo::getName));