【问题标题】:How to remove a map key when key and value are reseral [closed]当键和值是重新排列时如何删除映射键[关闭]
【发布时间】:2021-03-04 02:13:13
【问题描述】:

大家。我有一个问题,当映射包含反转值时,我想删除映射中的键,代码如下:

Map<Integer, Integer> test = new HashMap<>();
test.put(0, 1);
test.put(1, 0);
test.put(2, 1);
test.put(3, 2);

在上面的代码中,您可以看到 0-1 和 1-0,但我只想在地图上存在一个,例如 0-1 或 1-0。因此,我必须删除一个或多个以仅在地图上保留一个。在这种情况下,结果应该类似于 0,1 和 2,1。我的意思是在这种情况下,结果在地图上保留了两个元素。谁能帮助我,我非常感谢。

【问题讨论】:

  • 你想保留每一对中的哪一个? 'reseral' 是什么意思?
  • 您的用例是什么?要实现,您几乎必须拥有一个包含每个映射方向的地图,就像现在一样。所以问题可能实际上是“我如何以这种方式使用这张地图。”
  • 反转是指map中包含的key和value是否反转。如下数据:1,2; 2,1 在这种情况下,key 和 value 是相反的。只有一个保持,但没有具体。 1,2是正确的,2,1也是正确的
  • 谢谢你的回答,其实我有一个问题但可能很难描述,所以我只是提取了我认为应该用这个映射问题解决的问题。
  • 只遍历条目:对于每个条目,如果映射包含作为另一个键的值,则通过迭代器删除当前条目。

标签: java collections java-8 java-stream


【解决方案1】:

您可以创建一个自定义过滤器方法来仅保留不同的元素。保持它对所有类型的通用性,它可能是这样的:

public static <T,E> Predicate<T> distinctByKey(Function<? super T, E> keyExtractor)
{
    Map<Object, Boolean> map = new ConcurrentHashMap<>();
    return element -> map.putIfAbsent(keyExtractor.apply(element), Boolean.TRUE) == null;
}

因为我们需要检查两个元素是否都存在,但顺序并不重要,我们可以(ab)使用 Set 来创建某种组合键,其中顺序不重要。你也可以在这里创建你自己的对象,使用自定义的 equals/hashCode,这样我们就不再需要 Set

完整代码:

public static void main(String[] args) {
    Map<Integer, Integer> test = new HashMap<>();
    test.put(0, 1);
    test.put(1, 0);
    test.put(2, 1);
    test.put(3, 2);

    Map<Integer, Integer> uniques = test.entrySet().stream()
            .filter(distinctByKey(entry -> Set.of(entry.getKey(), entry.getValue())))
            .collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue()));

    System.out.println(uniques);
}

public static <T,E> Predicate<T> distinctByKey(Function<? super T, E> keyExtractor)
{
    Map<Object, Boolean> map = new ConcurrentHashMap<>();
    return element -> map.putIfAbsent(keyExtractor.apply(element), Boolean.TRUE) == null;
}

结果

{0=1, 2=1, 3=2}

【讨论】:

    【解决方案2】:

    这应该可以解决问题:

    Map<Integer, Integer> filtered = new HashMap<>();
    for(Map.Entry<Integer, Integer> e : test.entrySet()) {
        if(!Objects.equals(e.getKey(), filtered.get(e.getValue()))) {
            filtered.put(e.getKey(), e.getValue());
        }
    }
    

    这是另一个 sn-p,虽然我更喜欢第一个。

    Map<Integer, Integer> filtered2 = new HashMap<>();
    test.forEach((k, v) -> {
        if(!Objects.equals(k, filtered2.get(v))) {
            filtered2.put(k, v);
        }
    });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-10-23
      • 2013-10-30
      • 1970-01-01
      • 2019-04-15
      • 1970-01-01
      • 2016-09-15
      • 2017-05-19
      • 1970-01-01
      相关资源
      最近更新 更多