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
的导入。玩得开心。它确实使比较更容易并且更不容易出错(想象一下两个名称相似的方法,而你错误地抓住了错误的方法......发现错误很有趣;-))。
我有一个 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
的导入。玩得开心。它确实使比较更容易并且更不容易出错(想象一下两个名称相似的方法,而你错误地抓住了错误的方法......发现错误很有趣;-))。