Java 流压缩两个列表

Java streams zip two lists

我有一个 HashSet of Persons。一个人有名字、姓氏和年龄,例如:Person("Hans", "Man", 36)

我的任务是获取 17 岁以上人员的列表,按年龄对他们进行排序,并将名字与姓氏连接起来 像:["Hans Man"、"another name"、"another name"]

我刚刚被允许导入:

import java.util.stream.Stream; import java.util.stream.Collectors; import java.util.List; import java.util.ArrayList;

我的想法是先对它们进行排序,将名称映射到单独的流中,然后将它们压缩,但这行不通。

public static void getNamesOfAdultsSortedByAge(Stream<Person> stream){

    Stream<Person> result = stream;
    Stream<Person> result1 = result.filter(p -> p.getAge() >= 18)
                            .sorted((x, y) -> Integer.compare(x.getAge(),y.getAge()));


    Stream<String> firstName = result1.map(Person::getFirstName);
    Stream<String> lastName = result1.map(Person::getLastName);

    Stream<String> result3 = concat(firstName, lastName);

    List<String> result4 = result3.collect(Collectors.toList());

    System.out.println(result4);
}

提前致谢

这行不通:

Stream<String> firstName = result1.map(Person::getFirstName);
Stream<String> lastName = result1.map(Person::getLastName);

在第一个 map 之后,Stream 的类型 String 不适合 Person::getLastName。您需要在第一个 map() 调用自身中进行连接。

内部getNamesOfAdultsSortedByAge方法:

stream
    .filter(p -> p.getAge() > 17)
    .sorted(Comparator.comparingInt(Person::getAge))
    .map(person -> person.getFirstName() + " " + person.getLastName())
    .collect(Collectors.toList())

我想它应该能满足您的需求。 filter 过滤只有 18 岁或以上的人,第二行排序由 getAge 谓词给出,第三行只是将 Person 实例映射到包含 %firstName% %lastName% 的字符串,第四行收集结果进入列表。

public static void main(String[] args) {
    final List<String> matching = Lists.newArrayList(
            new Person("Joey", "Tribiani", 28),
            new Person("Rachel", "Green", 12),
            new Person("Ross", "Geller", 114),
            new Person("Chandler", "Bing", 17)).stream()
            .filter(person -> person.getAge() > 17)
            .sorted(Comparator.comparing(Person::getAge))
            .map(person -> person.getFirstName() + " " + person.getLastName())
            .collect(toList());
}

如果您需要更改排序顺序,只需反转比较器即可:

Comparator.comparing(Person::getAge).reversed()

您可以使用:

public static void getNamesOfAdultsSortedByAge(Stream<Person> stream) {
    List<String> sorted = stream.filter(p -> p.getAge() >= 18)
                                .sorted((x, y) -> Integer.compare(x.getAge(),y.getAge()))
                                .map(e -> e.getFirstName() + " " + e.getLastName())
                                .collect(Collectors.toList());
    System.out.println(sorted);
}

这里我们只是 map 通过连接名字和姓氏的排序流,之后我们使用 .collect() 终端操作将其收集到列表中。

我会使用以下内容,由于您对导入有奇怪的规则,我故意隐藏了那个 Comparator

List<String> result = stream.filter(p -> p.getAge() >= 18)
                            .sorted(java.util.Comparator.comparingInt(Person::getAge))
                            .map(p -> p.getFirstName() + " " + p.getLastName())
                            .collect(Collectors.toList());

注意:我知道一些规则暗示除 "allowed list of dependencies" 中列出的依赖项外不应使用其他依赖项,但我从未听说过只允许使用 4 个导入的规则但不允许最重要的之一。如果 Comparator 是一个内部 interface/class 我能理解,但它是一个必不可少的接口。如果您编写 (x, y) -> Integer.compare(x.getAge(),y.getAge()),您甚至可以将它用作功能接口,所以我真的不明白为什么不允许这种导入。话虽这么说:我的解决方案不需要您使用 java.util.Comparator 的导入。玩得开心。它确实使比较更容易并且更不容易出错(想象一下两个名称相似的方法,而你错误地抓住了错误的方法......发现错误很有趣;-))。