1

让我们想象一下这种情况 - 我想在 java 中使用 TreeMap。它是Colletions 框架的一部分,也是SortedMap 接口的唯一实现。

public class MyDictionary extends TreeMap<String, String> {
// some code
}

为了浏览存储在我的 Dictionary 类中的条目,我需要一种 Map.Entry。在代码中的某处(可能是 MyDictionary 类的一个方法,或者更可能是包装类中包含 MyDictionary 类变量的方法,其中包含我的数据)会有类似的内容:

public void showEntries() {
  for (Map.Entry<String, String> e : dictionary) {
    System.out.println(e.getKey(), e.getValue());  // do something
  }
}

现在的问题是:有没有办法将 Map.Entry 的泛型类型绑定到为 TreeMap 声明的泛型类型?

目标是只在一个地方定义泛型类型。

如果我稍后决定更改 TreeMap 中保存的数据类型,我将不必搜索使用这些类型的所有位置。

上面的例子是一个概念验证。请帮忙。

4

2 回答 2

3

您可以使MyDictionary类泛型,类型参数匹配TreeMap

public class MyDictionary<K, V> extends TreeMap<K, V>

然后,您可以在整个班级中引用这些类型参数。具体来说:

for (Map.Entry<K, V> e : dictionary) {

或者,如果您知道键和值将始终是同一类型:

public class MyDictionary<E> extends TreeMap<E, E>

for (Map.Entry<E, E> e : dictionary) {
于 2013-05-29T20:12:23.820 回答
0

这可以通过使用两个适配器来实现——一个用于入口,一个用于迭代器。

首先,在 Dictionary 中,创建您的 Entry 适配器,例如:

public static class Entry implements Map.Entry<String, String> {
  private Map.Entry<String, String> entry;

  Entry(Map.Entry<String, String> entry) {
    this.entry = entry;
  }

  @Override
  public String getKey() {
    return entry.getKey();
  }

  @Override
  public String getValue() {
    return entry.getValue();
  }

  @Override
  public String setValue(String value) {
    return entry.setValue(value);
  }
}

为了能够在 foreach 循环中使用 Dictionary 类,您必须实现 Iterable 接口。TreeMap 没有实现它。

public class Dictionary extends TreeMap<String, String> implements Iterable<Dictionary.Entry>

你可以像这样编写你的 iterator() 方法:

@Override
public Iterator<Entry> iterator() {
  return new Iterator<Entry>() {
    Iterator<Map.Entry<String, String>> wrapped = entrySet().iterator();

    @Override
    public boolean hasNext() {
      return wrapped.hasNext();
    }

    @Override
    public Entry next() {
      return new Entry(wrapped.next());
    }

    @Override
    public void remove() {
      wrapped.remove();
    }
  };
}

现在,您可以享受使用没有泛型类型的 foreach 循环:

for (Dictionary.Entry e : dictionary) {
  System.out.println(e.getKey() + " " + e.getValue());
}
于 2013-05-29T21:27:35.457 回答