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

Java8:使用过滤器/谓词和析取

锺离飞尘
2023-03-14

有两个具有相同结构的地图,即map1和map2,其结构为Map

地图1包含以下项目:
(“i1”,True),(“i2”,True),(“i3”,False),(“i4”,True)
地图2包含以下项目:
(“i1”,True),(“i2”,False),(“i3”,True),(“i5”,True)

我需要两种信息:
信息1:map1TrueMoreThanMap2True=2
因为我们正在比较地图条目,所以map1TrueMoreThanMap2True是2
在这种情况下,map1和map2之间的差异是:
map1-(“i2”,True)、(“i4”,True)

信息2:map1falsemorethan map2false=1
在这种情况下,map1和map2之间的差异是:
map1-(“i3”,False)

我通过写下面的代码来实现这一点:

 Map<String, Boolean> trueCountMap1 = map1.entrySet().stream()
                .filter(p -> p.getValue() == Boolean.TRUE)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

        Map<String, Boolean> trueCountMap2 = map2.entrySet().stream()
                .filter(p -> p.getValue() == Boolean.TRUE)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

        Map<String, Boolean> falseCountMap1 = map1.entrySet().stream()
                .filter(p -> p.getValue() == Boolean.FALSE)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

        Map<String, Boolean> falseCountMap2 = map2.entrySet().stream()
                .filter(p -> p.getValue() == Boolean.FALSE)
                .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
        map1TrueMoreThanMap2True = (CollectionUtils.disjunction(trueCountMap1.entrySet(), trueCountMap2.entrySet())
                .size())/2;
        map1FalseMoreThanMap2False = (CollectionUtils
                .disjunction(falseCountMap1.entrySet(), falseCountMap2.entrySet()).size())/2;

我认为上面的代码很冗长。有更好的方法吗??


共有2个答案

朱海超
2023-03-14

您可以定义一种在内部使用partitioning by方法

static Map<Boolean, Set<Map.Entry<String, Boolean>>> partition(Map<String, Boolean> map){
      return map.entrySet()
                .stream()
                .collect(Collectors.partitioningBy(Map.Entry::getValue, 
                                                   Collectors.toSet()));
}

现在,你可以做到:

Map<Boolean, Set<Map.Entry<String, Boolean>>> firstResultSet = partition(map1);

Map<Boolean, Set<Map.Entry<String, Boolean>>> secondResultSet = partition(map2);

调用firstResultSet。get(true)将返回一组地图条目,其中每个条目键的对应值为true

反过来调用firstResultSet。get(false)将返回一组映射条目,其中每个条目键的对应值为false

可以对secondResultSetmap执行同样的操作,以检索对应的map条目集。

夏烨霖
2023-03-14

据我所知,你想知道有多少map1的条目映射到true(分别是false)并与map2的条目不同。将析取的大小减半是行不通的。当所有键都保证相同时,它会起作用,但在您的示例数据中,有不同的键,“i4”仅出现在map1中,“i5”仅出现在map2中,这两个键似乎都映射到了相同的值。一旦其中一个映射到不同的值,您的方法就会失败。

直接实现“映射到true(分别为false)的map1条目的数量”要简单得多,并且与map2的条目不同,而不是处理集合操作:

int map1TrueMoreThanMap2True   = (int)map1.entrySet().stream()
    .filter(e ->  e.getValue() && !map2.getOrDefault(e.getKey(), false))
    .count();
int map1FalseMoreThanMap2False = (int)map1.entrySet().stream()
    .filter(e -> !e.getValue() && map2.getOrDefault(e.getKey(), true))
    .count();

如果您愿意,可以在一个Stream操作中执行此操作:

Map<Boolean,Long> result = map1.entrySet().stream()
    .filter(e -> e.getValue() ^ map2.getOrDefault(e.getKey(), !e.getValue()))
    .collect(Collectors.partitioningBy(Map.Entry::getValue, Collectors.counting()));
int map1TrueMoreThanMap2True   = result.get(true).intValue();
int map1FalseMoreThanMap2False = result.get(false).intValue();
 类似资料:
  • 问题内容: 我想做类似的事情: Python的标准库中是否有类似行为? 我知道在这里自己动手很容易,但是我正在寻找一种更标准的方法。 问题答案: 您可以使用filter方法: 或列表理解: 要查找单个元素,可以尝试: 尽管如果没有匹配项将引发异常,因此您可能希望将其包装在try / catch中。方括号()使之成为生成器表达式,而不是列表理解。 就我个人而言,尽管我只是使用常规的过滤器/理解并采用

  • 我试图创建一个从最终用户抽象谓词使用的类。 我的应用程序使用了番石榴重试扩展,效果很好。 我可以很容易地用谓词调用它,它会轮询,直到谓词返回false。 现在,也许我误解了谓词,但我正在尝试创建一个类来抽象它们。 我想这样称呼它 所以我写了如下PollCondition类。 但是MyPoller。poll()调用无法编译-未声明结果。 知道吗?

  • 如何使用java8流和过滤器过滤嵌套循环? 假设我有一个汽车列表(

  • 本文向大家介绍Objective-C语言用谓词过滤数组,包括了Objective-C语言用谓词过滤数组的使用技巧和注意事项,需要的朋友参考一下 示例 更多关于 NSPredicate: 苹果文档:NSPredicate

  • 问题内容: 我有一个清单,我想分成几个小清单。 说出所有包含“ aaa”的项目,所有包含“ bbb”的项目以及更多谓词。 我该如何使用java8? 我看到了这篇文章,但只拆分为2个列表。 我看到了这篇文章,但是在Java 8之前已经很老了。 问题答案: 就@RealSkeptic中解释的那样,注释只能返回两个结果:true和false。这意味着您将只能将数据分为两组。 您需要的是某种可以让您确定应

  • 使用java stream,我有一个ClassA列表,应用于流以进行过滤,所以使用List。stream()。过滤器(谓词)。这样,谓词就需要ClassA的谓词来应用,但我真的想要String的谓词,因为ClassA。Field1是字符串类型。因此,与其让谓词包含f- 缺少的链接是什么,我需要如何转换流才能做到这一点? 对于其他上下文,在过滤之后,我需要从过滤列表中提取第二个字段,因此目标是拥有C