【问题标题】:Confusion over the syntax: Set<String> set = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new))语法混淆: Set<String> set = people.stream().map(Person::getName).collect(Collectors.toCollection(TreeSet::new))
【发布时间】:2016-06-24 18:26:20
【问题描述】:

我正在努力学习Java的Set接口,在网上遇到了下面的代码,我明白这段代码的目的是将一个Collection&lt;Object&gt;转换成一个TreeSet,但是我不明白如何语句有效,因为语法对我来说很复杂且陌生。有人可以逐步指导我完成整个过程吗?

Set<String> set = people.stream()
                        .map(Person::getName)
                        .collect(Collectors.toCollection(TreeSet::new));

另外,在什么样的情况下,我们应该更喜欢上面的语法而不是下面的语法?

Set<Integer> s1 = new TreeSet(c1); //where c1 is an instance of Collection interface type

【问题讨论】:

  • “还有,在什么情况下我们应该更喜欢上面的语法而不是下面的语法?” 它们做不同的事情,所以它们不能互换。 map 操作只能通过流进行。
  • 对不起,如果我的问题听起来很愚蠢,但他们不是都在创建 TreeSet 的实例吗?
  • 是的,但是map 操作是第一个sn-p 的重点。你有例如List&lt;Person&gt; 并希望将其转为 Set&lt;String&gt;。你不能用 TreeSet 构造函数来做到这一点。
  • 另外,哇,刚刚注意到一些完全不相关的东西。 new TreeSet(c1) 真的很糟糕。这称为raw type,您可以通过这种方式造成堆污染。 c1 不必是 Integer 的集合。它可以是例如List&lt;String&gt; 并且代码将编译,但是您只是偶然将 String 放入了 IntegerSet 中。很难调试,因为当您尝试从s1 中提取内容时,您会在完全不同的地方得到ClassCastException。 (不过,编译器会警告你。)

标签: java collections set java-8 java-stream


【解决方案1】:

people.stream()

取一组人,得到一个流。

.map(Person::getName)

获取一个人流并对每个人调用getName 方法,返回一个包含所有结果的列表。这将“等效于”

for(Person person : people){
    setOfNames.add(person.getName())
}

.collect(Collectors.toCollection(TreeSet::new));

获取字符串流并将其转换为集合。


当您需要应用多个转换时,流非常有用。如果您使用并行流,它们也可以很好地执行,因为每个转换(在您的情况下是每个 getName)都可以并行完成而不是顺序完成。

【讨论】:

    【解决方案2】:

    peopele.stream() 创建一个元素流 .map(Person::getName) 从 people 集合中获取每个对象并调用 getName ,然后转换为字符串 .collect(Collectors.toCollection(TreeSet::new)) - 收集这些 String 元素并从中创建一个 TreeSet。

    希望清楚

    【讨论】:

    • 非常感谢您的帮助!如果我错了,请纠正我,但是“人”变量是“人”类实例的集合吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-10-31
    • 2017-11-08
    • 2019-08-26
    • 1970-01-01
    • 2021-04-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多