我有以下方法:
public static List<List<String>> createObject() {
List<List<String>> listOfListOfStrings = new LinkedList<List<String>>();
List<String> listOfStrings = new LinkedList<String>();
//do some populating on the lists here
listOfListOfStrings.add(listOfStrings);
return listOfListOfStrings;
}
现在我希望能够使用ArrayList / Vector / Stack而不是LinkedList (并根据需要做不同的组合。我读了一些有关此问题的泛型的帖子,我发现了使用工厂模式创建最适合 (因为我不想反射,因为使用通用<T extends List<K>, K extends List<String>>
将不起作用< / b>。)。所以我想出的解决方案如下:
public class Tester {
public static void main(String[] args){
checkGenericsOfLists();
}
public static void checkGenericsOfLists(){
List<List<String>> listOfListOfStrings = createObject(new LinkedListFactory<List<String>>(), new LinkedListFactory<String>());
print(listOfListOfStrings);
translate(listOfListOfStrings);
print(listOfListOfStrings);
}
public static List<List<String>> createObject(ListFactorable mainListFactory, ListFactorable subListsFactory) {
List<List<String>> listOfListOfStrings = mainListFactory.create();//new LinkedList<List<String>>();
List<String> listOfStrings = subListsFactory.create();//new LinkedList<String>();
listOfStrings.add("A");
listOfListOfStrings.add(listOfStrings);
return listOfListOfStrings;
}
public static void transform(List<List<String>> listOfListOfStrings){
//do some abuse on the lists here.
}}
此解决方案发出警告:
ListFactorable是原始类型。对泛型类型ListFactorable的引用应该参数化
这适用于createObject方法签名。和
类型安全:类型List的表达式需要未经检查的转换以符合字符串列表列表&gt;&gt;
这适用于工厂调用create()方法的行。
但如果我使用这个:
public static List<List<String>> createObject(ListFactorable<List<List<String>>, List<String>> mainListFactory, ListFactorable<List<String>, String> subListsFactory) {
List<List<String>> listOfListOfStrings = mainListFactory.create();//new LinkedList<List<String>>();
List<String> list = subListsFactory.create();//new LinkedList<String>();
list.add("A");
listOfListOfStrings.add(list);
return listOfListOfStrings;
}
我收到编译错误:
The method createObject(ListFactorable<List<List<String>>,List<String>>, ListFactorable<List<String>,String>) in the type Tester is not applicable for the arguments (LinkedListFactory<List<String>>, LinkedListFactory<String>)
有什么方法可以让编译器不抛出警告或错误,并且在没有createObject方法知道所使用的List实现的情况下(在编译期间)实例化这些列表?!
干杯,
霸
修改: 请原谅我没有发布其他课程(非常愚蠢的我:))。我们走了:
public interface ListFactorable<T extends List<K>, K> {
T create();}
public class LinkedListFactory<K> implements ListFactorable<LinkedList<K>, K> {
public LinkedList<K> create(){
return new LinkedList<K>();
}}
EDIT2(Eugene承担问题):
public interface EugeneListFactorable<T extends List<?>> {T create();}
public class EugeneLinkedListFactory implements EugeneListFactorable<LinkedList<?>> {
public LinkedList<?> create(){
return new LinkedList<List<?>>();
}
}
public static void checkGenericsOfLists2(){
List<List<String>> listOfListOfStrings = createObject(new EugeneLinkedListFactory(), new EugeneLinkedListFactory());
translate(listOfListOfStrings);
}
编译器错误:
- Type mismatch: cannot convert from LinkedList<?> to List<List<String>>
- Bound mismatch: The generic method createObject(EugeneListFactorable<N>, EugeneListFactorable<M>) of type
Tester is not applicable for the arguments (EugeneLinkedListFactory, EugeneLinkedListFactory). The inferred type LinkedList<?>
is not a valid substitute for the bounded parameter <N extends List<List<String>>>
请尝试编译并运行我发布的示例和您的解决方案。它是一个测试类,您可以在您的IDE上轻松运行。谢谢!
答案 0 :(得分:2)
以下内容“在我的机器上运行”,没有任何警告或错误。我不知道的是所有大惊小怪的原因 - 请参阅秒代码块。
public class Tester {
public static void main(String[] args) {
checkGenericsOfLists();
}
public static void checkGenericsOfLists() {
List<List<String>> listOfListOfStrings = createObject(
new LinkedListFactory<List<String>>(),
new LinkedListFactory<String>());
transform(listOfListOfStrings);
}
public static List<List<String>> createObject(
ListFactorable<List<List<String>>, List<String>> mainListFactory,
ListFactorable<List<String>, String> subListsFactory
)
{
List<List<String>> listOfListOfStrings = mainListFactory.create();
List<String> listOfStrings = subListsFactory.create();
listOfStrings.add("A");
listOfListOfStrings.add(listOfStrings);
return listOfListOfStrings;
}
public static void transform(List<List<String>> listOfListOfStrings) {
// do some abuse on the lists here.
System.out.println(listOfListOfStrings);
}
public interface ListFactorable<T extends List<K>, K> {
T create();
}
static public class LinkedListFactory<K> implements ListFactorable<List<K>, K> {
public LinkedList<K> create() {
return new LinkedList<K>();
}
}
}
这个解决方案有点清洁,省去了一些泛型噪音。
public class Tester2 {
public static void main(String[] args) {
checkGenericsOfLists();
}
public static void checkGenericsOfLists() {
List<List<String>> listOfListOfStrings = createObject(
new LinkedListFactory<List<String>>(),
new LinkedListFactory<String>());
transform(listOfListOfStrings);
}
public static List<List<String>> createObject(
ListFactory<List<String>> mainListFactory,
ListFactory<String> subListsFactory
)
{
List<List<String>> listOfListOfStrings = mainListFactory.create();
List<String> listOfStrings = subListsFactory.create();
listOfStrings.add("A");
listOfListOfStrings.add(listOfStrings);
return listOfListOfStrings;
}
public static void transform(List<List<String>> listOfListOfStrings) {
// do some abuse on the lists here.
System.out.println(listOfListOfStrings);
}
public interface ListFactory<T> {
List<T> create();
}
static public class LinkedListFactory<T> implements ListFactory<T> {
public List<T> create() {
return new LinkedList<T>();
}
}
}
答案 1 :(得分:1)
这不能完全解决您的问题,但它有助于更快地找到解决方案。
当你有任何看起来像这样的事情时X&gt;考虑重构成一个类。我举一个例子。你看起来像是在使用翻译。现在我不确切地知道你的目标是什么,因为你没有说明,但一种常见的方法是:
List<String> english = new LinkedList<String>();
List<String> french = new LinkedList<String>();
List<String> spanish = new LinkedList<String>();
List<List<String>> languages = new LinkedList<List<String>>();
languages.add(english);
languages.add(french);
languages.add(spanish);
for(String word : someWordList) {
for(List<String> language : languages) {
// oh snap! I really have no idea what language I'm working in...
// I could do something silly like make list.get(0) be the language
// name, but that seems lame
}
}
更好的是这样的事情:
class Language {
final String language;
final Map<String,String> english2current;
Language(String language, Set<String> words) {
this.language = language;
english2current = new HashMap<String,String>();
Translator t = TranslatorFactory.getTranslator(language);
for(String word : words) english2current.put(word,t.translate(word));
}
}
Collection<String> wordSet() {
return english2current.values();
}
现在没有看到更多的实施,很难确切地看到你做错了什么。但是无论你做什么,看看删除任何嵌套的泛型,而是试图将它们分离成类。这将允许您以面向对象的方式合并行为,并更好地组织您的逻辑,以便您可以专注于它应该做的事情而不是泛型的语义。
答案 2 :(得分:0)
你需要正确的ListFactorable类:
public class ListFactorable<T extends List<?>> {
public T create() {
...
}
}
然后createObject方法看起来像这样:
public static <N extends List<List<String>>,M extends List<String>> N createObject( //
ListFactorable<N> mainListFactory, //
ListFactorable<M> subListsFactory) {
N listOfListOfStrings = mainListFactory.create();//new LinkedList<List<String>>();
M listOfStrings = subListsFactory.create();//new LinkedList<String>();
listOfStrings.add("A");
listOfListOfStrings.add(listOfStrings);
return listOfListOfStrings;
}