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

查找具有公共值的映射集条目

沃皓轩
2023-03-14

我有一个收藏如下

Map<String, Set<Long>> myMap = new HashMap<>();

我想知道这张地图上是否有任何条目被设置为同一张地图的另一个条目。

例如,让我们说地图有以下5个条目

a - {1, 2, 3}
b - {4, 5}
c - {1}
d - {2, 3}
e - {5}
f - {6}

因此,它可能有以下重叠项

a - {1, 2, 3}  and c - {1} 
b - {4, 5}     and e - {5}
a - {1, 2, 3}  and d - {2, 3}

或者只是一组按键列表,比如

a and c
b and e
a and d

我可以迭代每个键集,然后对每个键集使用disjoint或anyMatch,但我想知道是否有一种优化方法(Java8、9、10、11)。

共有2个答案

顾乐心
2023-03-14

MapSet中的元素数降序排序,即排序Map中的第一个条目包含包含最多元素的Set。在您的示例中,这将是以下条目:

a - {1, 2, 3}

排序后,取第二个条目,查看其集合是否是第一个条目的集合的子集。第二个条目是

b - {4, 5}

d - {2, 3}

然后取第三个条目,看看它的集合是第二个条目还是第一个条目的子集。继续,直到到达最后一个条目。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

public class Subsets {

    public static void main(String args[]) {
        Map<String, Set<Long>> myMap = Map.of("a", Set.of(1L, 2L, 3L),
                                              "b", Set.of(4L, 5L),
                                              "c", Set.of(1L),
                                              "d", Set.of(2L, 3L),
                                              "e", Set.of(5L),
                                              "f", Set.of(6L));
        List<String> sortedKeys = myMap.entrySet()
                                       .stream()
                                       .sorted((e1, e2) -> (e2.getValue() == null ? 0 : e2.getValue().size()) - (e1.getValue() == null ? 0 : e1.getValue().size()))
                                       .map(e -> e.getKey())
                                       .collect(Collectors.toList());
        String[] keyArray = new String[sortedKeys.size()];
        sortedKeys.toArray(keyArray);
        List<String[]> subsets = new ArrayList<>();
        for (int i = 1; i < keyArray.length; i++) {
            Set<Long> source = myMap.get(keyArray[i]);
            for (int j = i - 1; j >= 0; j--) {
                Set<Long> target = myMap.get(keyArray[j]);
                if (target.containsAll(source)) {
                    subsets.add(new String[]{keyArray[i], keyArray[j]});
                }
            }
        }
        subsets.forEach(arr -> System.out.println(Arrays.toString(arr)));
    }
}

执行上述代码时产生的输出如下:

[d, a]
[e, b]
[c, a]

换句话说:

  • da
  • 的子集
  • eb
  • 的子集
  • ca
  • 的子集

嵌套的for循环的总迭代次数是15次,即O(nlog2n),而另一个答案是36次迭代,即O(n2)。

请注意,如果可以按排序顺序创建初始的映射,则无需执行排序。一种方法是使用LinkedHashMap作为映射实现。

myMap = new LinkedHashMap<>();
myMap.put("a", Set.of(1L, 2L, 3L));
myMap.put("b", Set.of(4L, 5L));
myMap.put("d", Set.of(2L, 3L));
myMap.put("c", Set.of(1L));
myMap.put("e", Set.of(5L));
myMap.put("f", Set.of(6L));
尹昀
2023-03-14

我相信这是可能的通过流。但在这种情况下,嵌套循环也可以。

import java.util.*;

class Main {
    public static void main(String[] args) {
        Map<String, Set<Long>> myMap = new HashMap<>();

        myMap.put("a", Set.of( 1l, 2l, 3l ));
        myMap.put("b", Set.of( 4l, 5l ));
        myMap.put("c", Set.of( 1l ));
        myMap.put("d", Set.of( 2l, 3l ));
        myMap.put("e", Set.of( 5l ));
        myMap.put("f", Set.of( 6l ));

        for(String aKey : myMap.keySet())
            for(String bKey : myMap.keySet())
                if(!aKey.equals(bKey) &&  myMap.get(aKey).containsAll(myMap.get(bKey))) 
                    System.out.println(aKey + " - " + myMap.get(aKey) + " and " + bKey + " - " + myMap.get(bKey));
    }
}
 类似资料:
  • 问题内容: 我有单独的“类”和“组”集,每个组都分配了一个或多个标签。我想为每个组找到包含每个组相同(或更多)标签的类的子集。 一些样本数据: 并输出: 结果集示例如下所示: 结果输出: 我了解这是一个涉及和的关系划分类型问题。这些帖子描述了我想做的事情,但我不知道 问题答案: 我认为这也应该起作用

  • 假设我有一组字符串和一个散列函数(或任何单边函数)和一个测试函数。我想用Java8流创建一个从输入字符串到通过测试函数的哈希值的映射。我的问题是如何在中编写? 看来老的for循环是最简洁的解决方案。

  • 我有一个注册选民的XML文档,一个地址可能有多个人。我想迭代地为每个不同的地址(数字和街道)选择节点。然后,我的目标是能够把一个地址的所有居民的名字集合成一行。例如“Robert and Olga BBBBBB”,或“Jennifer eeeee and James FFFF”,或“Desmond AAAAAA”。 我只是需要有关XPath查询的帮助。如果LINQ是答案,我也想听听。你能帮我解决这

  • 需要帮助请在MyBank jEE申请。问题是hibernate能够创建表,但它不能插入数据这里是我的代码 以下是为什么它不能回答数据到数据库的错误

  • 2.7 ABP公共结构 - 对象之间的映射 2.7.1 简介 我们通常需要在近似的对象之间进行映射处理。这是一个重复且枯燥无味的工作,通常来说两个需要相互映射的对象之间有近似的或者相同的属性。思考一下这样一个案例:应用服务的方法: public class UserAppService : ApplicationService { private readonly IRepository<

  • 问题内容: 使用Hibernate,可以创建一个组合ID,其中要映射到该ID的列之一可以为空值吗? 这是为了处理具有唯一键的旧表,该键可以具有空值,但不能具有主键。 我意识到我可以只向表中添加一个新的主键列,但是我想知道是否有任何方法可以避免这样做。 问题答案: 否。主键不能为null。