Список списков списков

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

Ответы

Ответ 1

Все остальные ответы технически правильны, но IMHO, если вы реализуете грубый список списков списков, вы не обрабатываете свои данные на нужном уровне абстракции. Например, я уверен, что список списков уже означает "что-то" в вашей бизнес-области. Инкапсулируйте это "что-то" в другой объект, чтобы вы могли просто иметь List <Something → → > <. < Список < Объект → → .

Ответ 2

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

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

Ответ 3

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

  • Создайте тип данных, чтобы выразить свои данные, инкапсулируя детали структуры или, по крайней мере,

  • Создайте тип ключа, который обертывает 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);
        }
    }
}

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

Ответ 4

Хотя верно, что вы можете построить List < List < List < any → > в 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

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

Ответ 5

Полный пример, показывающий список-список с коллекциями и генериками (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