【问题标题】:Variable initialization from intermediate result从中间结果初始化变量
【发布时间】:2017-10-01 11:48:48
【问题描述】:

有时,当源代码变得复杂时,我会发现阅读以下语句会让人感到困惑:

Set<Integer> odds = new HashSet<>(ints); // not yet true
odds.removeAll(evens); // now it's true

我想知道是否有一种巧妙的方法可以避免 odds 包含偶数值的行。类似的东西:

(Set<Integer> odds = new HashSet<>(ints)).removeAll(evens); // doesn't compile

我可以使用双括号初始化,

Set<Integer> odds = new HashSet<Integer>(ints) {{ removeAll(evens); }};

但这显然很糟糕for multiple reasons

这是另一个可以编译的 example hack,但它看起来更像是一个笑话:

Set<Integer> odds = (odds = new HashSet<>(ints)).retainAll(evens) ? odds : odds

我想到的最后一个(在写这篇文章时)似乎没问题,尽管它使用了两行:

Set<Integer> odds;
(odds = new HashSet<Integer>(ints)).removeAll(evens);

还有其他想法吗?

【问题讨论】:

  • Set&lt;Integer&gt; odds = (new HashSet&lt;&gt;(ints)).removeAll(evens); 不工作吗?
  • @Berger 不,removeAll 无效。
  • 我看到这被描述为“时间耦合”

标签: java


【解决方案1】:

我不知道你为什么要把事情复杂化。只要你能得到evens的集合,你当然可以对odds做同样的事情。

那么你可以简单地做:

Set<Integer> oddsSet = new HashSet<>(odds);

或者,您可以将最后一个示例压缩成一行:

Set<Integer> odds; (odds = new HashSet<Integer>(ints)).removeAll(evens);

我为我的无知道歉,但我认为这个问题具有学术性质,其他建议的答案可能不一定能弥补不惜一切代价没有额外的线路,例如使用流几乎肯定会比真正的收藏。

【讨论】:

  • 如果你不考虑赔率和偶数,我认为希望能够以惯用的方式创建 SetC = SetA - SetB 是完全合理的
  • @Michael 我不傻,确实明白了问题的重点,但认为人们会觉得我的回答很有趣,哈哈;我不认为投反对票是公平的。
  • 开玩笑的答案应该留在问题的 cmets 中(如果有的话!)。我试图找到一个来源,但没有太多运气。没有什么私人的!
【解决方案2】:

使用流:

Set<Integer> odds =
    ints.stream().filter(x -> x % 2 == 1).collect(Collectors.toSet());

如果你想同时把集合分成奇数和偶数:

Map<Boolean, Set<Integer>> oddsAndEvens =
    ints.stream().collect(
        Collectors.partitioningBy(x -> x % 2 == 0, Collectors.toSet()));
Set<Integer> evens = oddsAndEvens.get(true);
Set<Integer> odds = oddsAndEvens.get(false);

【讨论】:

  • 至少对于retainAll() 操作我认为这是一个好方法:ints.stream().filter(evens::contains).collect(Collectors.toSet())
  • @steffen 假设您能够构建 evens;那么你在构建它时肯定会遇到同样的问题。
  • @AndyTurner 在示例中,我们也确实有evens,所以这没什么区别。实际上,我发现您的回答很有帮助,我只是想补充一点,方法参考可能像@Michael 所说的那样不清楚。对于removeAll(),我们需要to negate the predicate
  • 虽然这解决了奇数/偶数情况,但对于 通用情况,您希望通过从另一组中减去一组来创建一个新组(全部在一个单行)?
  • @Michael 我发现这种方法更通用,因为您可以自己定义结果,无论是通过使用包含等谓词进行过滤,还是通过限制(第一个随机 5)或通过元素转换。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-30
  • 2013-10-09
  • 1970-01-01
  • 1970-01-01
  • 2013-08-30
相关资源
最近更新 更多