Java流压缩两个列表

时间:2018-11-29 10:43:27

标签: java java-8 java-stream concat

我有一个HashSet of Persons。一个人的名字,姓氏和年龄如下:Person(“ H​​ans”,“ Man”,36)

我的任务是获取17岁以上的人的列表,并按年龄对其进行排序,并将firstName与lastName合并 像:[“ Hans Man”,“另一个名字”,“另一个名字”]

我只允许导入:

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

先谢谢您

5 个答案:

答案 0 :(得分:3)

您可以使用:

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()终端操作将其收集到列表中。

答案 1 :(得分:1)

这不起作用:

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

在第一个map之后,Stream的类型为String,不适合Person::getLastName。您需要在第一个map()调用本身内进行合并。

答案 2 :(得分:1)

内部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%的字符串,第四个收集结果进入列表。

答案 3 :(得分:1)

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

答案 4 :(得分:1)

我将使用以下内容,并且由于您对导入有一些奇怪的规则,因此我故意将其隐藏在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());

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