2012-07-19 65 views
1

我已经写了一个TrieMap<V> implements Map<String,V>类,它显然是从字符串键入的。这工作正常。为没有键的映射实现entrySet

我想加强它与更一般的CharSequence键。除了最后一个问题,我相信我已经实现了转换,我无法创建K类型的对象。

现在签名现在必须成为TrieMap<K extends CharSequence,V> implements Map<K,V>。问题是,我相信你知道,TrieMap实际上并不存储原始密钥。 (实际上这是它的主要价值之一,因此它通常占用的空间比普通地图少得多。)

要实现Set<Entry<K, V>> entrySet()因此我必须以某种方式制造K类型的对象。有什么方法可以实现吗?

+0

@dfb:难点不是将键创建为String实例。难点在于创建K型键,而不知道K是什么。 – 2012-07-19 15:08:54

+0

侧面问题:在TrieMap 实现Map '时,以下问题/答案的优点是什么? – dfb 2012-07-19 19:48:30

+0

@dfb - 不确定你在问什么,但工厂方法的好处在于创建者提供了创建密钥的机制,因为由于类型擦除,只有创建者知道正在使用哪种类型。我觉得现在有点像星际迷航中的VGer。 :) – OldCurmudgeon 2012-07-20 00:42:06

回答

3

我会定义以下接口:

public interface KeyBuilder<K extends CharSequence> { 
    public K build(CharSequence value); 
} 

,并提供接口给TrieMap构造方法的实现。当你需要建立一个新的K实例时,你可以让接口去做。

您可能会使用更适合您的数据结构的内容作为build方法的参数,CharSequence只是一种可能性。如果你想要做一些更复杂,你可以构建这样的:

public interface KeyFactory<K extends CharSequence> { 
    public KeyBuilder<K> newBuilder(); 
} 

public interface KeySequence<K extends CharSequence> { 
    public KeySequence<K> append(char value); 
    public K build(); 
} 

随着String实现:

public class StringKeyFactory<String> { 
    public KeyBuilder<String> newBuilder() { 
     return new KeyBuilder<String>() { 
      private final StringBuilder s = new StringBuilder(); 
      public KeySequence<String> append(char value) { 
       s.append(value); 
       return this; 
      } 
      public String build() { 
       return s.toString(); 
      } 
     }; 
    } 
} 
+0

这应该工作。你能想到我可以通过任何方式为最常见的CharSequence实现者(如String和StringBuilder)预先构建工厂,并自动选择合适的工具吗?我想这可能是我的一个工厂,比如'newStringMap()'等。这是一种耻辱,我不能在构造函数中询问泛型类型。 – OldCurmudgeon 2012-07-19 15:13:04

+0

我认为静态构造函数是最简单和最干净的选择。 – Flavio 2012-07-19 15:19:59

+0

我选择了一个更简单的接口,一个'K toK(CharSequence key)'方法,它可以从CharSequence中创建一个'K'。否则这是一个完美的解决方案。 – OldCurmudgeon 2012-07-20 00:51:13

0

不,我不明白怎么会是可能的,而不采取Factory<K>作为你的构造函数中的参数。根据您在TrieMap中的元素,此Factory<K>将负责创建K的实例。