[英]Java collect with lambda expression example
我试图转换这个
String r = "";
for ( Persona p : list ) {
r += p.lastName;
}
to stream().filter.collect()
表单,但我想知道如何使用lambda表达式 (而不是方法引用)编写collect
。 我找不到一个很好的例子。
这就是我所拥有的
class B {
public static void main( String ... args ) {
List<Person> p = Arrays.asList(
new Person("John", "Wilson"),
new Person("Scott", "Anderson"),
new Person("Bruce", "Kent"));
String r;
String s = p.stream()
.filter( p -> p.lastName.equals("kent"))
.collect((r, p) -> r += p.lastName);/// ?????
}
}
class Person {
String name;
String lastName;
public Person( String name, String lastName ) {
this.name = name;
this.lastName = lastName;
}
}
我发现的所有示例都使用方法引用,而我认为应该有一种简单的方法来编写lambda表达式。
假设您不想使用任何现成的收集器,如Collectors.joining()
,您确实可以创建自己的收集器。
但是,正如javadoc所指出的那样, collect()需要3个功能接口实例作为参数,或者需要收集器。 所以你不能只将一个lambda表达式传递给collect()。
假设你想使用第一个版本,取3个lambda表达式,你会注意到,通过读取javadoc,结果必须是一个可变对象,并且String不可变。 所以你应该使用StringBuilder。 例如:
StringBuilder s =
p.stream()
.filter( p -> p.lastName.equals("kent"))
.map(p -> p.lastName)
.collect(StringBuilder::new,
StringBuilder::append,
StringBuilder::append);
这使用方法引用,但所有方法引用都可以写为lambda表达式。 以上相当于
StringBuilder s =
p.stream()
.filter( p -> p.lastName.equals("kent"))
.map(p -> p.lastName)
.collect(() -> new StringBuilder(),
(stringBuilder, string) -> stringBuilder.append(string),
(stringBuilder1, stringBuilder2) -> stringBuilder1.append(stringBuilder2));
您还可以使用.reduce()
函数,它比collect更容易阅读。
String s = p.stream()
.filter( p -> p.lastName.equals("kent"))
.reduce("", (acc, p) -> acc + p.lastName(), String::concat);
StringBuilder
版本:
StringBuilder s = p.stream()
.filter( p -> p.lastName.equals("kent"))
.reduce(new StringBuilder(), (acc, p) -> acc.append(p.lastName()), StringBuilder::append);
也许你正在设想一个reduce
操作而不是一个collect,这将允许你使用像你想象的lambda表达式。 例如,
String s = persons.stream()
.map( (s1, str) -> s1.concat(str) )
.reduce("", String::concat);
当然,这是一项练习。 字符串连接效率低下,因此最好使用collect(Collectors.joining())
,它使用StringBuffer
作为累加器。
您可以省略使用此解决方案的映射:
Collector<Person, StringBuilder, String> collector = Collector.of(
StringBuilder::new,
(buf, person) -> buf.append( person.lastName ),
(buf1, buf2) -> {
buf1.append( buf2 );
return( buf1 );
},
buf -> buf.toString()
);
list.stream()
.filter( p -> p.lastName.equals( "Kent" ) )
.collect( collector );
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.