【问题标题】:Deleting the treeMap entries with null values删除具有空值的 treeMap 条目
【发布时间】:2016-11-06 14:17:59
【问题描述】:

我正在尝试删除所有空值,但如果最后一个键的 treeSet 为空,那么它仍然存在。所以我在想如果最后一个条目为空,如何删除它。由于这是一个treeMap,我认为我可以通过使用 tm.lastKey() 访问它来获取最后一个元素,但该方法似乎不存在。所以这个问题是双重的。首先,有没有办法删除包括最后一个在内的所有空值,第二个是 .lastKey() 方法在哪里?

public class Timing {
    private static Map<String, SortedSet> tm = new TreeMap<String, SortedSet>();

    public static Map manipulate() {
        SortedSet ss = new TreeSet();
        ss.add("APPL");
        ss.add("VOD");
        ss.add("MSFT");

        tm.put("2019-09-18",null);
        tm.put("2019-09-21",ss);
        tm.put("2019-09-22", null);
        tm.put("2019-09-20",ss);
        tm.put("2019-09-19", null);
        tm.put("2019-09-23",null);

        return tm;
    }

    public static void printMap() {
        for (String s: tm.keySet()) {
            System.out.println(s + ": " + tm.get(s));
        }
    }

    // Will delete all but the last one
    public static void deleteNull() {
        Set set = tm.entrySet();
        Iterator i = set.iterator();
        Map.Entry me = (Map.Entry) i.next();
        // there is no tm.lastKey()??
        while(i.hasNext()) {
            if (me.getValue() == null) {
                i.remove();
            }
            me = (Map.Entry) i.next();
        }
    }
}

【问题讨论】:

  • 不要使用原始类型。
  • 您的tmMap&lt;&gt;TreeMap 的方法自然不会显示在上面。

标签: java dictionary treemap


【解决方案1】:

要从地图中删除所有值为 null 的条目,您可以将 deleteNull 方法替换为

tm.values().removeIf(Objects::isNull);

【讨论】:

  • 确实很优雅
【解决方案2】:

Java TreeMap 确实指定了 lastKey() 方法。您可以在Java-Doc 中查看TreeMap

问题是,您无法访问该方法,因为您将地图的真实类型隐藏到您的方法中。你可以在这里看到它:

private static Map<String, SortedSet> tm = new TreeMap<String, SortedSet>();

由此,您的方法只知道tmMap 对象,而那些没有lastKey() 方法。将 Map 更改为 TreeMap 或在您的方法中进行强制转换,然后它将起作用。

备选方案 1:

private static TreeMap<String, SortedSet> tm = new TreeMap<String, SortedSet>();

备选方案 2:

public String lastKey() {
    if (tm instanceof TreeMap<?, ?>) {
        return ((TreeMap<String, SortedSet>) tm).lastKey();
    } else {
        // Error!
    }
}

【讨论】:

    【解决方案3】:

    最简单的方法是在 while 循环结束后再次运行检查迭代器,如下所示:

    while(i.hasNext()) {
        if (me.getValue() == null) {
            i.remove();
        }
        me = (Map.Entry) i.next();
    }
    if (me.getValue() == null) {
        i.remove();
    }
        me = (Map.Entry) i.next();
    

    这样你会捕捉到最后一个值。

    但是,您可以使用与打印地图类似的键集。

    Set<String> keySet = tm.keySet();
    for(int ndx = 0; ndx < keySet.size(); ndx++){
        String key = keySet.get(ndx);
        if(tm.get(key) == null){
            tm.remove(key);
        }
    }
    

    【讨论】:

    • 删除某些条目后集合的大小不会改变吗?那么我们要么得到多线程异常,要么得到 indexout of bounds?
    • 不错的尝试,但在我看来,最简单的方法是 Modus 的回答 :)
    猜你喜欢
    • 2014-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多