Список списков списков - PullRequest
14 голосов
/ 23 июня 2010

Я новичок в Java и мне нужно составить список списков списков. Я мог бы сделать это в python, потому что элемент списка может быть списком, поэтому во встроенном списке list[0] будет ссылаться на список, а list[0][0] будет ссылаться на нулевой элемент встроенного списка. Есть ли простой способ реализовать это поведение в Java?

Ответы [ 5 ]

26 голосов
/ 23 июня 2010

Все остальные ответы технически правильны, но ИМХО, если вы реализуете грубый список списков списков, вы не обрабатываете свои данные на должном уровне абстракции. Например, я почти уверен, что список списков уже означает «что-то» в вашей бизнес-сфере. Инкапсулируйте это «что-то» в другой объект, чтобы вы могли просто иметь List вместо сложного в использовании и обслуживании List >>.

12 голосов
/ 23 июня 2010

Как говорит Марио , вам, вероятно, нужно абстрагироваться от ваших данных немного дальше.Но следующее будет делать то, что вам нужно.

В Java вам нужно что-то вроде:

List<List<List<Object>>> listOfListsOfLists =new ArrayList<List<List<Object>>>();

Затем, чтобы получить доступ к элементам, вы должны использовать:

listOfListsOfLists.get(a).get(b).get(c);

Или перебирать все:

for (List<List<Object>> list2: listOfListsOfLists) {
    for (List<Object> list1: list2) {
        for (Object o: list1) {
            // use `o`
        }
    }
}
5 голосов
/ 23 июня 2010

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

  1. создаете тип данных для выражения своих данных при инкапсуляции деталей структуры, либопо крайней мере

  2. Создать тип ключа, который оборачивает int [] (но корректно переопределяет equals и hashCode) и вместо этого использовать HashMap?Как правило, редко когда вся ваша трехмерная структура будет сильно заполнена.

Еще лучше, если бы вы могли инкапсулировать эту карту и использовать varargs для чистого доступа.

public class NDimensionalArray<V> {
    private final int dimensions;
    private final Map<Key, V> values = new HashMap<Key, V>();

    private NDimensionalArray(int dimensions) {
        this.dimensions = dimensions;
    }

    public V get(int... indices) {
        checkIndices(indices);
        return values.get(new Key(indices));
    }

    public void set(V value, int... indices) {
        checkIndices(indices);
        values.put(new Key(indices), value);
    }

    private void checkIndices(int[] indices) {
        if ( indices.length != dimensions ) {
            throw new IllegalArgumentException();
        }
    }

    private static final class Key {
        private final int[] indices;

        private Key(int[] indices) {
            this.indices = indices;
        }

        @Override
        public int hashCode() {
            return Arrays.hashCode(indices);
        }

        @Override
        public boolean equals(Object obj) {
            return Arrays.equals(indices, ((Key)obj).indices);
        }
    }
}

Если у людей есть примеры установленных библиотек коллекций, которые уже делают подобные вещи, дайте мне знать, и я добавлю ссылки.

3 голосов
/ 23 июня 2010

Хотя это, безусловно, правда, что вы можете создать список> В Java я не могу не задаться вопросом, почему вы хотите это сделать?Не то чтобы немыслимо, что это лучшее решение вашей проблемы, но ничего себе, например, почему?

Полагаю, я мог бы представить что-то вроде

public class Employee ...
List<Employee> store; // all the employees in a store
List<List<Employee>> city; // all the store lists for a city
List<List<List<Employee>>> nation; // all the store lists for the nation

Но вы бы действительно хотели обработать это?сюда?Я не знаю, это зависит от того, что вам нужно с этим делать.

2 голосов
/ 23 июня 2010

Подробный пример, показывающий список-список с коллекциями и обобщениями (Java 1.5 +)

// declare the list of lists
List<List<String>> listOfListOfStrings = new ArrayList<List<String>>();

// populate
List<String> listOfStrings = new ArrayList<String>(); // one inner list
listOfStrings.add("one-one");
listOfStrings.add("one-two");
listOfListOfStrings.add(listOfStrings);

listOfStrings = new ArrayList<String>(); // and another one
listOfStrings.add("two-one");
listOfStrings.add("two-two");
listOfListOfStrings.add(listOfStrings);

// access
String oneOne = listOfListOfStrings.get(0).get(0);   // first element of first inner list
String twoTwo = listOfListOfStrings.get(1).get(1);   // second element of second inner list
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...