【问题标题】:Is there a Java Map class that satisfies these needs? [duplicate]是否有满足这些需求的 Java Map 类? [复制]
【发布时间】:2021-02-24 23:37:46
【问题描述】:

是否有满足这些功能的 Java Map 类:

  1. 它是一个具有UnknownMap<Key, Object> 形式的通用类,我计划在基于节点的应用程序中使用它,其中每个节点都存储在此映射中并对应于一个浮点值对象,如UnknownMap<Float, Node>

  2. 它可以存储可以映射到相同浮点值的对象,例如:

UnknownMap<Float, String> map = new UnknownMap<Float, String>();
map.put(1, "a");
map.put(2, "b");
map.put(3, "c");
map.put(1, "d");
System.out.println(map);

将打印出:{1="a", 1="d", 2="b", 3="c"} 而不是:{1="d", 2="b", 3="c"}

  1. 它有一个名为subMap 的方法,该方法返回一个包含键范围内所有节点的映射,类似于TreeMap.subMap

  2. 它必须对浮点键值执行二进制搜索以检索正确的对象,而不是遍历整个集合。它需要快速,因为可能会有数千个甚至数百万个节点。

这样的类是否存在,或者我必须从头开始编写一个?

谢谢。

【问题讨论】:

  • 听起来你在寻找 Guava 的 TreeMultimap
  • 否 - 因为根据定义,Map 不能有重复的键。如果您的数据结构具有灵活性,那么您可以使用几个不同的 Map 实现来解决这个问题。
  • 糟糕的标题,缺乏细节。你的问题不清楚。我猜您想将键映射到值集合而不是单个值。如果是这样,这个问题已经在 Stack Overflow 上解决了很多次。

标签: java dictionary hashtable


【解决方案1】:

TreeMap 将完成这项工作。将“值”部分设为列表(或可能的集合)以处理“一个键可以映射到多个值”子句:

public void put(float k, String v) {
    map.computeIfAbsent(k, k_ -> new ArrayList<String>()).add(v);
}

例如。

【讨论】:

  • 语法是map.putIfAbsent(50f, new ArrayList&lt;String&gt;()).add("a"); 并且第一次为key会抛出一个NPE。
  • 呃,实际上,我的错误是我打算在那里写computeIfAbsent。我会继续编辑它。
【解决方案2】:

使用Map.computeIfAbsent 试试这样:

第一次遇到键时,它会创建一个列表并将字符串添加到其中。下一次,它只是将字符串添加到列表中。这是一种将多个值映射到同一个键的技术。

Map<Float,List<String>> map = new HashMap<>();      
map.computeIfAbsent(10f, k->new ArrayList<>()).add("a");
System.out.println(map);
map.computeIfAbsent(10f, k->new ArrayList<>()).add("b");
System.out.println(map);                 
map.computeIfAbsent(30f, k->new ArrayList<>()).add("c");
System.out.println(map);                 
map.computeIfAbsent(30f, k->new ArrayList<>()).add("d");
System.out.println(map);                 
map.computeIfAbsent(10f, k->new ArrayList<>()).add("e");
System.out.println(map);

每次添加后打印以下内容以查看地图变化。

{10.0=[a]}
{10.0=[a, b]}
{30.0=[c], 10.0=[a, b]}
{30.0=[c, d], 10.0=[a, b]}
{30.0=[c, d], 10.0=[a, b, e]}

您还可以使用与Map.compute() 类似的技术将新字符串连接到现有字符串。因为 lambda 中的变量必须是有效的 final,所以这很容易通过在方法中隔离映射来完成。

Map<Float, String> map2 = new HashMap<>();
add(10f, "a", map2);
add(10f, "b", map2);
add(30f, "c", map2);
add(30f, "d", map2);
add(10f, "e", map2);
        
map2.entrySet().forEach(System.out::println);

打印

30.0=c, d
10.0=a, b, e

方法

    
public static void add(float key, String value, Map<Float, String> map) {
    map.compute(key,
            (k, v) -> v == null ? value : v + ", " + value);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-30
    • 2018-03-04
    • 2015-02-27
    • 1970-01-01
    相关资源
    最近更新 更多