当前位置: 首页 > 知识库问答 >
问题:

如果只有一个值[duplicate],则返回一个值的Java8收集器

夹谷和裕
2023-03-14

我对函数式编程和流的东西有点陌生,但我所知道的一点非常有用!

List<SomeProperty> distinctProperties = someList.stream()
    .map(obj -> obj.getSomeProperty())
    .distinct()
    .collect(Collectors.toList());

if (distinctProperties.size() == 1) {
    SomeProperty commonProperty = distinctProperties.get(0);
    // take some action knowing that all share this common property
}
Optional<SomeProperty> universalCommonProperty = someList.stream()
    .map(obj -> obj.getSomeProperty())
    .distinct()
    .collect(Collectors.singleOrEmpty());

我认为singleorepty除了与distince结合使用之外,还可以在其他情况下使用。当我还是uber n00b的时候,我花了很多时间重新设计Java集合框架,因为我不知道它在那里,所以我试着不重复我的错误。Java是否提供了一种很好的方法来完成singleorepty的事情?我说错了吗?

谢谢!

编辑:下面是一些distinct案例的示例数据。如果忽略映射步骤:

Optional<SomeProperty> universalCommonProperty = someList.stream()
    .map(obj -> obj.getSomeProperty())
    .distinct()
    .collect(Collectors.singleOrEmpty());

[]     -> Optional.empty()
[1]    -> Optional.of(1)
[1, 1] -> Optional.of(1)
[2, 2] -> Optional.of(2)
[1, 2] -> Optional.empty()
Optional<SomeProperty> loneSpecialItem = someList.stream()
    .filter(obj -> obj.isSpecial())
    .collect(Collectors.singleOrEmpty());

[special]           -> Optional.of(special)
[special, special]  -> Optional.empty()
[not]               -> Optional.empty()
[not, special]      -> Optional.of(special)
[not, special, not] -> Optional.of(special)
Optional<Int> value = someList.stream().collect(Collectors.singleOrEmpty())
[]     -> Optional.empty()
[1]    -> Optional.of(1)
[1, 1] -> Optional.empty()

共有1个答案

蒯慈
2023-03-14

只计算前两个元素的“Hacky”解决方案:

    .limit(2)
    .map(Optional::ofNullable)
    .reduce(Optional.empty(),
        (a, b) -> a.isPresent() ^ b.isPresent() ? b : Optional.empty());

一些基本的解释:

单个元素[1]->映射到[可选(1)]->减少DO

"Empty XOR Present" yields Optional(1)
"Empty XOR Present" yields Optional(1)
"Optional(1) XOR Optional(2)" yields Optional.Empty

下面是完整的测试案例:

public static <T> Optional<T> singleOrEmpty(Stream<T> stream) {
    return stream.limit(2)
        .map(Optional::ofNullable)
        .reduce(Optional.empty(),
             (a, b) -> a.isPresent() ^ b.isPresent() ? b : Optional.empty());
}

@Test
public void test() {
    testCase(Optional.empty());
    testCase(Optional.of(1), 1);
    testCase(Optional.empty(), 1, 1);
    testCase(Optional.empty(), 1, 1, 1);
}

private void testCase(Optional<Integer> expected, Integer... values) {
    Assert.assertEquals(expected, singleOrEmpty(Arrays.stream(values)));
}

感谢Ned(操作),他贡献了异或的想法和上面的测试案例!

 类似资料:
  • 问题内容: 我对这种函数式编程和流技术有点陌生,但是我所知道的一点却非常有用! 我遇到过几次这种情况: 我真正想要的是: 我认为,除了与结合使用外,该东西在其他情况下也可能有用。当我成为超级n00b时,我花了很多时间重新发明Java Collections Framework,因为我不知道它在那里,所以我试图不重蹈覆辙。Java是否提供了执行此操作的好方法?我说错了吗? 谢谢! 编辑:这是案例的一

  • 我是流运营商的忠实粉丝。它不在标准库中,但我发现它非常有用。如果流只有一个值,它将在中返回该值。如果它没有值或有多个值,则返回。 我之前问了一个问题,@ThomasJungblut想出了这个很棒的实现: 唯一的问题是,你必须把它放在你的电话开始时 而不是按顺序结束 这使得它比其他流机制更难阅读。 作为流处理的新手,有人知道如何在一系列流转换的末尾设置一个短路的< code > single emp

  • 假设我有以下工作的lambda表达式: 我想在过滤器语句之前创建一个具有2个值的流。所以我想做一个映射,但仍然保留原始值。我想实现这样的事情: 这可能与Java8流?我已经看了收集(GroupingBy()),但仍然没有成功。

  • 我的数据库中有两个表: 表1:购买物品 表1列出了购买的物品,表2每小时更新一次每件物品的当前价格。因此,从表2中可以清楚地看出,肉类最后一次交易是在2013年2月20日上午10点,而鱼类不是在同一天交易的,它是在2013年2月19日上午9点交易的,鸡肉是在2013年2月20日上午9点交易的。我想做的是,列出表1中的所有项目,并加入表2中各个项目的最后交易价格,如下所示: 这里应该应用什么类型的连

  • 问题内容: 我有这种简单的查询,它返回给定id的非空整数字段: 问题是,如果找不到ID,则结果集为空。我需要查询始终返回一个值,即使没有结果也是如此。 我有这个东西工作,但我不喜欢它,因为它运行相同子查询的2倍: 如果该行存在,则返回field1,否则返回0。有什么改进的方法吗? 谢谢! 编辑以下一些评论和答案 :是的,它必须在 单个查询语句中, 并且我不能使用count技巧,因为 我只需要返回1

  • 嗨,伙计们,查询只返回一行,即使我有12行。请帮忙