引用类型依赖项 - 声明Map.Entry依赖于为TreeMap声明的泛型类型

时间:2013-05-29 20:09:49

标签: java oop generics dependencies treemap

让我们想象一下这个场景 - 我想在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中保存的数据类型,我将不必搜索我使用这些类型的所有地方。

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

2 个答案:

答案 0 :(得分: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) {

答案 1 :(得分:0)

这可以通过使用两个适配器来实现 - 一个用于Entry,一个用于Iterator。

首先,在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());
}