Скрытые возможности Java - разъяснение инициализаторов ArrayList / instance - PullRequest
5 голосов
/ 26 мая 2011

В вопросе Скрытые возможности Java меня заинтересовал ответ об инициализаторах экземпляров .

Мне было интересно, как изменить эту строку:

List<Integer> numbers = new ArrayList<Integer>(){{ add(1); add(2); }};

, чтобы заставить его выполнять ту же работу с вложенными Arraylists:

ArrayList<ArrayList<Integer>> numbers = ...

это возможно?

Ответы [ 5 ]

4 голосов
/ 26 мая 2011
List<Integer> numbers = new ArrayList<Integer>(){{ add(1); add(2); }};

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

Используйте либо:

List<Integer> numbers = Arrays.asList(1, 2);

или

List<Integer> numbers = new ArrayList<Integer>(Arrays.asList(1, 2));

Для 2 уровней вы можете использовать:

List<List<Integer>> numbers = Arrays.asList(Arrays.asList(1, 2), Arrays.asList(2,3,4));

С помощью статического импорта вы можете даже сократить его до этого, если действительно хотите:

List<List<Integer>> numbers = asList(asList(1, 2), asList(2,3,4));
3 голосов
/ 26 мая 2011

Двойная инициализация стала намного менее интересной для списков, теперь, когда Arrays.asList принимает varargs, вы можете сделать это вместо этого:

List<List<Integer>> numbers = new ArrayList<List<Integer>>();
numbers.add(Arrays.asList(1,2));
numbers.add(Arrays.asList(3,4));

Или объединить с двойной скобкой, как это:

List<List<Integer>> numbers = new ArrayList<List<Integer>>() {{add(Arrays.asList(1,2)); add(Arrays.asList(3,4));}};

но то, соответствует ли он одной строке, зависит от правил форматирования кода вашего проекта. Это настолько ужасно многословно, что альтернативы начинают хорошо выглядеть. Как положить числа в строку и проанализировать ее. Или переключитесь на Scala, Groovy или Clojure, все из которых поддерживают синтаксис буквального списка.

2 голосов
/ 26 мая 2011

Я бы не использовал эту идиому для "упрощения" ArrayList объявлений.Это выглядит круто, но без необходимости создает анонимный подкласс ArrayList, и это выглядит слишком "волшебным" для моих вкусов ... Вам нужен код, который будет читаем и понятен следующему разработчику.

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

. Вот пример использования Lists.newArrayList (E ... elements) служебного метода Guava:

    import com.google.common.collect.Lists;


    List<ArrayList<Integer>> numbers = Lists.newArrayList(
            Lists.newArrayList(1, 2),
            Lists.newArrayList(3, 4)
    );

Или, что еще лучше, используя только интерфейс List слева (вам следует избегать использования конкретных классов в объявлениях переменных):

    import com.google.common.collect.Lists;


    List<List<Integer>> numbers = Lists.<List<Integer>>newArrayList(
            Lists.newArrayList(1, 2),
            Lists.newArrayList(3, 4)
    );

Если вы знаетеэти списки будут неизменными, еще лучше использовать ImmutableList :

    import com.google.common.collect.ImmutableList;


    List<List<Integer>> numbers = ImmutableList.<List<Integer>>of(
            ImmutableList.of(1, 2),
            ImmutableList.of(3, 4)
    );
2 голосов
/ 26 мая 2011

И, конечно, вы можете сделать то же самое для внутренних ArrayLists: хотя я думаю, что это становится довольно нечитаемым ...

    List<ArrayList<Integer>> numbers = new ArrayList<ArrayList<Integer>>()
    {
        {
            add(new ArrayList<Integer>()
            {
                {
                    add(1);
                    add(2);
                }
            });
            add(new ArrayList<Integer>()
            {
                {
                    add(1);
                    add(2);
                }
            });
        }
    };

хотя и не намного длиннее или хуже обычного способа (в зависимости от стиля вашей фигурной скобки!)

    List<ArrayList<Integer>> numbers = new ArrayList<ArrayList<Integer>>();
    ArrayList<Integer> list1 = new ArrayList<Integer>();
    ArrayList<Integer> list2 = new ArrayList<Integer>();
    list1.add(1);
    list1.add(2);
    list2.add(1);
    list2.add(2);
    numbers.add(list1);
    numbers.add(list2);

Подход Arrays.asList (1, 2), приведенный в других ответах, кажется самым приятным из всех.

1 голос
/ 26 мая 2011

Просто замените int объектом ArrayList<integer>

List<ArrayList<Integer>> numbers = new ArrayList<ArrayList<Integer>>() {

            {
                add(new ArrayList<Integer>());
                add(new ArrayList<Integer>());
            }
        };
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...