我有以下课程
ID<- seq(1:10)
Age_Group<-sample(c("Teen", "Adult", "Senior"), 10, replace = TRUE)
Tenure<-sample(c(1,2,3,4,5), 10, replace = TRUE)
Campaign_Response<-sample(c(T, F), 10, replace = TRUE)
Survey<-data.frame(Age_Group, Tenure, Campaign_Response)
如何创建像class Person {
public String name;
public int age;
public List<String> hobbies;
Person(String name, int age, List<String> hobbies)
{this.name = name; this.age = age; this.hobbies = hobbies;}
}
这样的爱好的年龄图?
我编写的Java 8方式是:
Map<Integer, Set<String>>
是否有更惯用的方法可以使用Map<Integer, Set<String>> collect8 = persons.stream()
.collect(
toMap(
p -> p.age,
p -> p.hobbies.stream().collect(toSet()),
(hobbies1, hobbies2) ->
Stream.concat(hobbies1.stream(), hobbies2.stream()).collect(toSet())
)
);
?
作为一个相关的问题,我发现没有Java流的版本更具可读性。
Collectors.groupingBy()
如果更容易阅读,我们应该使用非流代码吗?特别是当流式版本,如此处所示,没有中间流与数据的转换,但很快在终端操作中结束?
答案 0 :(得分:3)
查看Java 8 Collectors文档中的类似示例:
DTSTART:20170323T110000
DTEND:20170323T113000
你可以在这里使用相同的方法。
答案 1 :(得分:2)
正如您所指出的那样:Stream
解决方案可能与您当前的非Stream
解决方案不同。使用groupingBy
解决问题可能看起来不像您希望的那样,因为您希望将List
转换为Set
。
我使用groupingBy
,mapping
和reducing
构建了一个解决方案,但该解决方案并不容易阅读,甚至包含错误。您可以在以下位置详细了解相关内容:Java 8 stream.collect( ... groupingBy ( ... mapping( ... reducing ))) reducing BinaryOperator-usage我真的建议您查找Holger提供的答案,因为它还包含一个更简单的解决方案,使用自定义Collector
和一点点Outlook to Java 9&#39; { {1}},对我而言,接近你的非flatMapping
解决方案。
但是另一个使用Stream
的解决方案我想出来了,实际上有以下几点:
groupingBy
为此您需要以下导入:
Map<Integer, Set<String>> yourmap;
yourmap = personList.stream()
.flatMap(p -> p.hobbies.stream()
.flatMap(hobby -> Stream.of(new SimpleEntry<>(p.age, hobby)))
)
.collect(Collectors.groupingBy(Entry::getKey,
Collectors.mapping(Entry::getValue, Collectors.toSet())));
当然,您也可以选择import java.util.AbstractMap.SimpleEntry;
import java.util.Map.Entry;
或Tuple
或您最喜欢的内容。
但是在任何方面都不会更好。
我会继续使用您当前的非Pair
解决方案。它更具可读性,可以做它应该做的事情。