2016-05-23 2 views
1

Я использую класс StringMap, как показано ниже, чтобы упростить Карта объявление:Избавление от дженериков в карте

public interface StringMap extends Map<String, String> { 
    interface Entry extends java.util.Map.Entry<String, String>{ 

    } 
} 
public class StringHashMap extends HashMap<String, String> implements StringMap{ 

} 

Проблема заключается в том, что я не могу сделать StringMap.Entry работать так же, как StringMap. Если бы я это сделать:

StringMap strings = new StringHashMap(); // this works perfectly fine 
for (StringMap.Entry entry : strings.entrySet()) { // this doesn't work 
} 

Я получаю эту ошибку:

Error:(402, 49) java: incompatible types: java.util.Map.Entry<java.lang.String,java.lang.String> cannot be converted to com.nicksoft.nslib.StringMap.Entry 

Есть ли способ вокруг него?

Edit:

Я начинаю понимать, что это не возможно. По крайней мере, это невозможно с разумными усилиями. Думаю, если бы это было, я бы нашел, что кто-то другой это делает. Но если у кого-то есть трюки, которые могут сделать код более удобочитаемым - сообщите мне.

+0

Я считаю, что это будет классифицировать как [псевдо-typedef antipattern] (http://www.ibm.com/developerworks/java/library/j-jtp02216/index.html) –

+0

Тогда я действительно хотел бы реализовать это антипаттерн. Я не забочусь о шаблонах дизайна. Спасибо, что остановились и высказал свое мнение. – NickSoft

+0

@JornVernee Ну, я читал об этом, и да, это плохо, потому что вы не можете передать родительский класс, когда захочется наследник. Это отстой, что java не имеет typedef. Однако я не согласен с тем, что (не-псевдо) typedef - это плохо. Я думаю, когда вы хотите писать в java, вы должны следовать правилам java. Почему ты это написал? Теперь я не уверен, что хочу использовать его ... Я все же могу использовать его для внутренних объектов, которые никогда не выходят за пределы их класса. – NickSoft

ответ

1

Это потому, что метод entrySet() не перегружен, чтобы вернуть тип com.nicksoft.nslib.StringMap.Entry.

Как вы не можете переопределить метод entrySet(), чтобы заставить его вернуть свой собственный тип, то единственный вариант у вас есть, чтобы переименовать его:

public interface StringMap extends Map<String, String> { 
    interface Entry extends java.util.Map.Entry<String, String>{ 

    } 
    Set<Entry> myEntrySet(); 
} 
public class StringHashMap extends HashMap<String, String> implements StringMap{ 
    public Set<Entry> myEntrySet() { 
    //The implementation to return the set of your own entry type. 
    } 
} 

Тогда ваш цикл будет выглядеть следующим образом:

for (StringMap.Entry entry : strings.myEntrySet()) { 
} 
+0

Это то, что сработает, но я надеялся на что-то менее сложное. Я не хочу повторно реализовывать entrySet(). Что более важно, я не хочу делать копию записей, установленных каждый раз, когда я вызываю этот метод. Это не было бы оправдано, если бы код был более понятным (путем упрощения деклараций). – NickSoft

Смежные вопросы