Java 8 通过流连接字符串
我正在尝试加入一个姓名列表:Java 8 通过流连接字符串,java-8,Java 8,我正在尝试加入一个姓名列表: List<String> names; names = books.stream() .map( b -> b.getName() ) .filter( n -> ( (n != null) && (!n.isEmpty()) ) ) .collect(Collectors.joining(", ")); 有人能解释一下为什么吗?一些关于.map(b->b.getName())
List<String> names;
names = books.stream()
.map( b -> b.getName() )
.filter( n -> ( (n != null) && (!n.isEmpty()) ) )
.collect(Collectors.joining(", "));
有人能解释一下为什么吗?一些关于.map(b->b.getName())
和.map(Book::getName)
之间差异的说教性解释也很受欢迎,因为我认为我没有弄错。连接(“,””收集器将收集所有字符串并使用给定的分隔符将其连接到单个字符串中。在本例中,collect
的返回类型为String
,但您正试图将结果分配给列表
。如果要将字符串收集到列表中,请使用Collectors.toList()
如果您有一个包含Book
实例的集合,那么将Book
s流映射到String
s流一次就足够了
lamdba与方法参考的区别
- lamdba表达式可以写为一个块,包含多个操作:
如果lambda有单次操作,则可以缩短:b -> { // here you can have other operations return b.getName(); }
b -> b.getName()
- 方法引用只是一个简单操作的lambda的“快捷方式”。这样:
可替换为:b -> b.getName()
但是如果你有一个像这样的lambda:Book::getName
您不能使用对b -> b.getName().toLowerCase()
方法的引用,因为您正在对getName
进行额外的调用toLowerCase()
String names = books.stream()
.map( b -> b.getName() )
.filter(n -> (n != null) && !n.isEmpty())
.collect(Collectors.joining(", "));
Collectors.toList()是返回列表的集合:
List<String> namesList = books.stream()
.map( b -> b.getName() )
.filter(n -> (n != null) && !n.isEmpty())
.collect(Collectors.toList());
您还可以将此方法(不在书籍
类中)作为参数传递给map()
方法:
String names = books.stream()
.map(this::getReducedBookName)
.filter(n -> !n.isEmpty())
.collect(Collectors.joining(", "));
如果您更喜欢映射
而不是映射
作为字符串
String names = books.stream().collect(mapping(Book::getName,
filtering(s -> s != null && ! s.isBlank(),
joining(", "))));
作为列表
List<String> names = books.stream().collect(mapping(Book::getName,
filtering(s -> s != null && ! s.isBlank(),
toList())));
List name=books.stream().collect(映射(Book::getName,
筛选(s->s!=null&&!s.isBlank(),
toList());
好了,我现在明白我的愚蠢错误了。在Book::getName上使用b->b.getName()会有什么影响?方法引用可能会稍微高效一些,但实际上效率很低,所以这不应该影响设计决策。另一点是,Book::getName
引用声明类,因此,有时在使用b->b.getName()
时编译器无法推断b
的类型的情况下工作,尽管这也可以通过使用(Book b)->b.getName()来解决
then.Method引用也可能是危险的:你真的认为这样多的括号(.filter(n->)((n!=null)&&&(!n.isEmpty()))
比直接的.filter(n->n!=null&!n.isEmpty())提高了可读性吗
?嗯……我通常在任何时候使用括号,比如&&,只是为了清楚起见。在这种情况下,你是对的,它看起来很麻烦。我知道,&&
和|
之间的运算符优先级不是直观的答案,所以为了清楚起见,即使在不必要的地方,也要放括号。但是对于唯一的b->(b.getName())
,因此在另一个表达式处有一个外括号对是不一致的。等等….map(b->b.getName()).map(Book::getName)
有效,但只有.map(b->b.getName())
无效?因此书籍
实际上不是书籍
的集合?因此b.getName()
返回一本书籍
?可能这也是它不抱怨的原因。@user1156544,您应该在有问题的情况下编写它……这很混乱
String names = books.stream().collect(mapping(Book::getName,
filtering(s -> s != null && ! s.isBlank(),
joining(", "))));
List<String> names = books.stream().collect(mapping(Book::getName,
filtering(s -> s != null && ! s.isBlank(),
toList())));