如何将<String,Float> Map toString方法转换为通用Number版本

pet*_*ton 3 java generics

我有一个方法来获取Map的内容作为字符串,如下所示:

    public static String toStringStringFloatMap(Map<String, Float> stringFloatMap)
    {
        String entries = "";

        Iterator<Entry<String, Float>> it = stringFloatMap.entrySet().iterator();
        while (it.hasNext())
        {
            Map.Entry<String, Float> pair = it.next();
            entries += pair.getKey() + "=" + pair.getValue() + "\n";
        }

        return entries;
    }
Run Code Online (Sandbox Code Playgroud)

现在我正在尝试将其转换为Integer,Short,Double,....的通用版本.我用"?extends Number"替换了所有的Float,但.... entrySet().iterator(); 语句导致编译错误,并告诉我以下内容:

Type mismatch: cannot convert from Iterator<Map.Entry<String,capture#6-of ? extends Number>> to Iterator<Map.Entry<String,? extends Number>>
Run Code Online (Sandbox Code Playgroud)

我不知道"捕获#6-of?extends Number"是什么意思.谁能为我解释一下?

编辑:

正如安迪所指出的那样<?, ?>可能是最好的.

但我的问题仍然是为什么iterator()行无法传递编译器?

    public static String toStringMapError(Map<?, ?> map)
    {
        String entries = "";

        Iterator<Entry<?, ?>> it = map.entrySet().iterator(); <<<<<------- error lineeeeeee
        while (it.hasNext())
        {
            Map.Entry<?, ?> pair = it.next();
            entries += pair.getKey() + "=" + pair.getValue() + "\n";
        }

        return entries;
    }
Run Code Online (Sandbox Code Playgroud)

And*_*ner 8

如果你真的想要约束子类Number,声明一个类型变量,并在整个过程中使用:

public static <T extends Number> String toStringStringNumberMap(Map<String, T> stringFloatMap) {
    String entries = "";

    Iterator<Entry<String, T>> it = stringNumberMap.entrySet().iterator();
    while (it.hasNext())
    {
        Map.Entry<String, T> pair = it.next();
        entries += pair.getKey() + "=" + pair.getValue() + "\n";
    }

    return entries;
}
Run Code Online (Sandbox Code Playgroud)

但是你可以简单地使用?值:这里没有什么需要实例StringNumber具体的实例:你需要的只是实现类型toString(),这意味着任何子类Object都是可以接受的.

public static String toStringMap(Map<?, ?> map) { ... }
Run Code Online (Sandbox Code Playgroud)

您还可以使用增强的for语句,它比显式迭代器更整洁; 并且你应该总是StringBuilder在循环中使用while积累字符串,并避免构建不必要的临时字符串:

StringBuilder sb = new StringBuilder();
for (Map.Entry<?, ?> entry : map.entrySet()) {
  sb.append(entry.getKey());
  sb.append('=');
  sb.append(entry.getValue());
  sb.append('\n');
}
return sb.toString();
Run Code Online (Sandbox Code Playgroud)

  • 这里你需要的是具有`toString()`方法的键和值类型,即它们是`Object`的子类; 或者,您可以将任何内容存储为"地图"中的键和值.所以你可以把它变成`Map <?,?>`,然后就可以传递你喜欢的任何`Map`. (3认同)