Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sorting Java 8-按数组中定义的顺序按属性对对象集合排序_Sorting_Java 8_Java Stream - Fatal编程技术网

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