列表<列表<字符串>>仿制药问题

发布于 2024-12-07 15:28:19 字数 4384 浏览 0 评论 0 原文

我有以下方法:

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(如果需要,可以进行不同的组合。我阅读了一些有关此问题的泛型文章,并且我发现使用工厂模式来创建这些是最合适的(因为我不需要反射,并且因为使用通用,K扩展List> 不起作用。)。所以我想出的解决方案如下:

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类型的表达式需要未经检查的转换才能符合List of List of String>>

这是针对工厂调用 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 take on issues):

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 上运行。谢谢!

I have the following method:

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;
}

Now I want to be able to use an ArrayList/Vector/Stack instead of the LinkedList (and do different combinations if needed. I read some posts on generics regarding this issue and I found out that using a factory pattern for creating those is most suited (since I don't want reflection, and since using the generic <T extends List<K>, K extends List<String>> would not work.). So the solution I came up with is the following:

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.
}}

This solution gives warnings:

ListFactorable is a raw type. References to generic type ListFactorable should be parameterized

This is for the createObject method signature. And:

Type safety: The expression of type List needs unchecked conversion to conform to List of List of String>>

This is for the lines where the factory invokes the create() method.

But if I use this one:

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;
}

I get compiler error:

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>)

Is there any way I can make the compiler not throw warning or error and have those lists instantiated without the createObject method being aware of the List implementation used (during compile time)?!

Cheers,
Despot

EDIT:
Excuse me for not posting the rest of the classes (very silly of me:)). Here we go:

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 take on issue):

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);
}

Compiler error:

    - 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>>>

Please do try to compile and run the example I posted and your solution. Its a test class which you can easily run on ur IDE. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

夏雨凉 2024-12-14 15:28:19

以下内容“在我的机器上运行”,没有警告或错误。超出我的认知的是所有大惊小怪的原因 - 请参阅秒代码块。

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>();
        }
    }
}

The followin stuff "works on my machine" without warnings or errors. What is beyond my perception is the reason for all the fuss - see the seconds codeblock.

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>();
        }
    }
}

This solution is a little bit cleaner leaving out some generics noise.

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>();
        }
    }
}
草莓味的萝莉 2024-12-14 15:28:19

这并不能完全解决您的问题,但有助于更快地找到解决方案。

当你有任何看起来像这样的东西时 X>考虑重构为一个类。我将提供一个例子。你看起来像是在使用转换。现在我不知道你的目标是什么,因为你还没有说明它们,但一种常见的方法是:

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();
}

现在如果没有看到更多的实现,很难看看你到底做错了什么。但无论你在做什么,考虑删除任何嵌套的泛型,而不是尝试将它们隔离到类中。这将使您能够以面向对象的方式巩固行为,并更好地组织您的逻辑,以便您可以专注于它应该做什么,而不是泛型的语义。

This won't exactly solve your problem, but it will lend itself to finding the solution faster.

When you have anything that looks like this X> consider refactoring into a class. I'll provide an example. You look like you're using transations. Now I don't know exactly what your goals are, because you haven't stated them, but one common way to do it would be:

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
    }
}

What would be better would be something like this:

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();
}

Now without seeing more of your implementation it's hard to see exactly what you're doing wrong. But WHATEVER you're doing, look at removing any nested generics and instead trying to isolate them into classes. This will allow you to consolidate behavior in an object oriented manner, and better organize your logic so you can focus on what it's supposed to do instead of the semantics of generics.

野生奥特曼 2024-12-14 15:28:19

您需要正确的 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;
}

You need to properly ListFactorable class:

public class ListFactorable<T extends List<?>> {
  public T create() {
    ...
  }
}

Then createObject method could look something like this:

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;
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文