Почему у вас нет "List <List <String>>" в Java?

В Java, почему не работает следующая строка кода?

List<List<String>> myList = new ArrayList<ArrayList<String>>();

Он работает, если я изменяю его на

List<ArrayList<String>> myList = new ArrayList<ArrayList<String>>();

Сначала я подумал, что, возможно, у вас нет списков интерфейса, но я могу создать List<Runnable> просто отлично.

Идеи?

Общие типы более педантичны.

List означает List или любой подтип, но <List> означает только List. Если вам нужен подтип, вам нужно иметь <? extends List>

Я подозреваю, что вы можете использовать

List<List<String>> myList = new ArrayList<List<String>>();

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

// with one level of indirection its simple.
ArrayList alist = new ArrayList();
List list = aList; // all good
list = new LinkedList(); // alist is still good.

С generics вы можете иметь два уровня косвенности, которые могут дать вам проблемы, поэтому они более педантичны, чтобы избежать этих проблем.

// with two levels of indirection
List<ArrayList> alist = new ArrayList<ArrayList>();
List<List> list = (List) alist; // gives you a warning.
list.add(new LinkedList()); // adding a LinkedList into a list of ArrayList!!
System.out.println(alist.get(0)); // runtime error

печатает

Exception in thread "main" java.lang.ClassCastException: java.util.LinkedList
     cannot be cast to java.util.ArrayList
42
ответ дан 12 окт. '12 в 17:58
источник

Давайте начнем с этого:

    ArrayList<ArrayList<String>> myList = new ArrayList<ArrayList<String>>();

Это создает ArrayList, элементами которого являются ArrayLists.

Теперь предположим, что мы можем назначить это

    List<List<String>> myList2 = myList.

Теперь мы должны это сделать:

    myList2.add(new LinkedList<String>());

Но это означает, что мы добавили LinkedList в список, элементы которого должны быть ArrayLists. По электронной почте Ой!!!

На самом деле назначение myList to myList2 не является законным... и гарантирует, что невозможно добавить неправильный тип List<String> к объекту ArrayList<ArrayList<String>>. (Нет, Питер, это не просто педантизм:-))

9
ответ дан 12 окт. '12 в 18:01
источник

Только коллекцию верхнего уровня можно объявить как класс реализации, в то время как вложенные должны оставаться интерфейсами, пока вы фактически не создадите экземпляры:

List<List<String>> rootList = new ArrayList<List<String>>(); 

а затем, когда вы создаете элемент для входа, вы делаете его реализацией:

List<String> nodeList = new ArrayList<String>();
rootList.add(nodeList);
3
ответ дан 12 окт. '12 в 18:02
источник

Его сравнение Type с левой стороны (объявления) на Type с правой стороны (экземпляра). В левой части ваш тип List<String>, а справа - ArrayList<String>. Если вы жалуетесь на разницу.

Пожалуйста, обновите правую сторону (instatiation) как Список i.e.

   List<List<String>> myList = new ArrayList<List<String>>();

Это должно работать нормально.

1
ответ дан 12 окт. '12 в 18:02
источник

Я знаю, что это старый вопрос, но я просто хотел поделиться своей идеей.

Вместо создания списка списков я лично просто создаю список типов [] (List<Type[]> listArray = new ArrayList<Type[]>();), я генерирую отдельный список только типа (List<Type> list = new ArrayList<Type>();), а затем .add(list.toArray()). Таким образом, это проще и легче читать, чем синтаксис List of Lists, который запутывает.

Например, в недавнем проекте, где у меня был входной файл, где каждая строка с только "0" означала новую строку в оригинале (это был алгоритм шифрования):

String[] input = getInputContents(inFile);
List<String> currentBuffer = new ArrayList<String>();
List<String[]> buffers = new ArrayList<String[]>();

for(String line : input) {
    if(line.equals("0")) {
        buffers.add((String[])currentBuffer.toArray());
        currentBuffer = new ArrayList<String>();
    } else {
        currentBuffer.add(line);
    }
}
0
ответ дан 10 февр. '16 в 17:26
источник

list<list<string>> l1=new list<list<string>>(); разрешен, если список содержит еще один список внутри списка.

public final class CPanelXMLBuilder extends PanelXMLBuilder {

    public CPanelXMLBuilder(AuthenticatedUser pAuthenticatedUser, Map<String, Object> pSessionMap, Map<String, Object> pRequestMap, String pPanelTemplate) throws Exception {
        super(pAuthenticatedUser, pSessionMap, pRequestMap, pPanelTemplate, null);
    }

    public Map<String, Object> buildXMLDocument(List<List<String>> pDetailsList) {

        if (pDetailsList.size() == 1) {
            List<String> pCustomerDetail = pDetailsList.get(0);
            xmlDocument.getRootElement().getChild("E_SHOW1").setText(pCustomerDetail.get(0));
            xmlDocument.getRootElement().getChild("E_SHOW2").setText(pCustomerDetail.get(1));
            xmlDocument.getRootElement().getChild("E_SHOW3").setText(pCustomerDetail.get(2));
            xmlDocument.getRootElement().getChild("E_SHOW4").setText(pCustomerDetail.get(3));
            xmlDocument.getRootElement().getChild("E_SHOW5").setText(pCustomerDetail.get(4));
            xmlDocument.getRootElement().getChild("ServerTimestamp").setText(pCustomerDetail.get(5).substring(0, 19));
        } else {
            xmlDocument.getRootElement().getChild("AlertType").setText("INFO");
            xmlDocument.getRootElement().getChild("Alert").setText("There is no matching record.");
        }

        requestMap.put(RequestMapKeys.XML_DOCUMENT, xmlDocument);

        return requestMap;
    }

}
0
ответ дан 21 марта '17 в 13:03
источник