从 Map 反转 HashMap映射<布尔值,列表<字符串>>

发布于 2024-12-06 05:28:43 字数 719 浏览 3 评论 0 原文

是否有更优雅/内置的方法来反转 Hashmap 的键和值?

我目前有以下内容。

private Map<Boolean, List<String>> reverseMap(Map<String, Boolean> permissions) {
    List<String> allow = new ArrayList<String>();
    List<String> deny = new ArrayList<String>();
    Map<Boolean, List<String>> returnvalue = new HashMap<Boolean, List<String>>();

    for (Entry<String, Boolean> entry : permissions.entrySet()) {
        if(entry.getValue()) {
            allow.add(entry.getKey());
        } else {
            deny.add(entry.getKey());
        }
    }

    returnvalue.put(true, allow);
    returnvalue.put(false, deny);
    return returnvalue;
}

Is there a more elegant/built-in way to reverse the keys and values of a Hashmap?

I currently have the following.

private Map<Boolean, List<String>> reverseMap(Map<String, Boolean> permissions) {
    List<String> allow = new ArrayList<String>();
    List<String> deny = new ArrayList<String>();
    Map<Boolean, List<String>> returnvalue = new HashMap<Boolean, List<String>>();

    for (Entry<String, Boolean> entry : permissions.entrySet()) {
        if(entry.getValue()) {
            allow.add(entry.getKey());
        } else {
            deny.add(entry.getKey());
        }
    }

    returnvalue.put(true, allow);
    returnvalue.put(false, deny);
    return returnvalue;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

メ斷腸人バ 2024-12-13 05:28:44

GuavaBiMap 已经提供了一种反转其键值对的方法。也许您可以将相关 Map 的接口更改为 BiMap,或者使用以下代码:

private BiMap<Boolean, String> reverseMap(Map<String, Boolean> permissions) {
   BiMap<String, Boolean> bimap = HashBiMap.create(permissions);
   return bimap.inverse();
}

Guava's BiMap already provides a method for reversing its key-value pairs. Perhaps you could change the interface of the Map in question to BiMap, or else use the following code:

private BiMap<Boolean, String> reverseMap(Map<String, Boolean> permissions) {
   BiMap<String, Boolean> bimap = HashBiMap.create(permissions);
   return bimap.inverse();
}
欢烬 2024-12-13 05:28:43

您可以考虑使用 GuavaMultimap 实现。例如:

private Multimap<Boolean, String> reverseMap(Map<String, Boolean> permissions) {
   Multimap<Boolean, String> multimap = ArrayListMultimap.create();
   for (Map.Entry<String, Boolean> entry : permissions.entrySet()) {
      multimap.put(entry.getValue(), entry.getKey());
   }
   return multimap;
}

或者更一般地说:

private static <K, V> Multimap<V, K> reverseMap(Map<K, V> source) {
   Multimap<V, K> multimap = ArrayListMultimap.create();
   for (Map.Entry<K, V> entry : source.entrySet()) {
      multimap.put(entry.getValue(), entry.getKey());
   }
   return multimap;
}

You might consider using one of Guava's Multimap implementations. For example:

private Multimap<Boolean, String> reverseMap(Map<String, Boolean> permissions) {
   Multimap<Boolean, String> multimap = ArrayListMultimap.create();
   for (Map.Entry<String, Boolean> entry : permissions.entrySet()) {
      multimap.put(entry.getValue(), entry.getKey());
   }
   return multimap;
}

Or more generally:

private static <K, V> Multimap<V, K> reverseMap(Map<K, V> source) {
   Multimap<V, K> multimap = ArrayListMultimap.create();
   for (Map.Entry<K, V> entry : source.entrySet()) {
      multimap.put(entry.getValue(), entry.getKey());
   }
   return multimap;
}
叹梦 2024-12-13 05:28:43

我会做类似的事情(但如果你必须经常做这种事情,请考虑 Guava),只用 Set 替换 List (似乎更一致)并预填充反向映射:

private Map<Boolean, Set<String>> reverseMap(Map<String, Boolean> permissions) {
    Map<Boolean, Set<String>> returnvalue = new HashMap<Boolean, Set<String>>();
    returnvalue.put(Boolean.TRUE, new HashSet<String>());
    returnvalue.put(Boolean.FALSE, new HashSet<String>());
    for (Entry<String, Boolean> entry : permissions.entrySet()) 
        returnvalue.get(entry.getValue()).add(entry.getKey());
    return returnvalue;
}

I'd do something similar (but if you must do this kind of thing frequently, consider Guava), only replacing the List with Set (seems a little more consistent) and prefilling the reversemap:

private Map<Boolean, Set<String>> reverseMap(Map<String, Boolean> permissions) {
    Map<Boolean, Set<String>> returnvalue = new HashMap<Boolean, Set<String>>();
    returnvalue.put(Boolean.TRUE, new HashSet<String>());
    returnvalue.put(Boolean.FALSE, new HashSet<String>());
    for (Entry<String, Boolean> entry : permissions.entrySet()) 
        returnvalue.get(entry.getValue()).add(entry.getKey());
    return returnvalue;
}
你对谁都笑 2024-12-13 05:28:43

首先要注意的是,如果您的值只是 true 或 false,那么您实际上并不需要反向映射。如果你有更广泛的价值观,那就有意义了。

获取具有特定值的条目的一种简单(但不是很优雅)的方法是:

public static <T, E> Set<T> getKeysByValue(Map<T, E> map, E value) {
     Set<T> keys = new HashSet<T>();
     for (Entry<T, E> entry : map.entrySet()) {
         if (entry.getValue().equals(value)) {
             keys.add(entry.getKey());
         }
     }
     return keys;
}

您可以看到,如果您需要时不时地调用它,那么这不太好。拥有两个不同的地图(正向和反向)并向两者添加条目是有意义的。您不能使用 Bidi 映射,因为键和值之间不存在 1:1 关系。

更新:以下解决方案不起作用。请参阅评论。

您还可以考虑使用 TreeMap 并根据值对其进行排序。这样,您可以随时调用 map.entrySet() 来获得排序集(先拒绝条目,然后允许)。缺点是只有一套。

ValueComparator bvc =  new ValueComparator(map);
TreeMap<String,Boolean> sorted_map = new TreeMap(bvc);

class ValueComparator implements Comparator {
  Map base;

  public ValueComparator(Map base) {
      this.base = base;
  }

  public int compare(Object a, Object b) {
    return (Boolean)base.get(a).compareTo((Boolean)base.get(b));
  }
}

First thing to note is that you don't really need a reverse map if your values are only true or false. It will make sense if you have a broader range of values.

One easy (but not very elegant) way to get the entries with a specific value is:

public static <T, E> Set<T> getKeysByValue(Map<T, E> map, E value) {
     Set<T> keys = new HashSet<T>();
     for (Entry<T, E> entry : map.entrySet()) {
         if (entry.getValue().equals(value)) {
             keys.add(entry.getKey());
         }
     }
     return keys;
}

You can see that this is not so good if you need to call it every now and then. It makes sense to have two different maps (straight and reverse) and add entries to both. You can't use Bidi maps since there is no 1:1 relation between keys and values.

UPDATE: The following solution won't work. See comments.

You can also consider using a TreeMap and keep it sorted based on the value. This way you can have a sorted set by calling map.entrySet() any time (denies entries first, then allows). The drawback is that it is only one set.

ValueComparator bvc =  new ValueComparator(map);
TreeMap<String,Boolean> sorted_map = new TreeMap(bvc);

class ValueComparator implements Comparator {
  Map base;

  public ValueComparator(Map base) {
      this.base = base;
  }

  public int compare(Object a, Object b) {
    return (Boolean)base.get(a).compareTo((Boolean)base.get(b));
  }
}

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文