java: Понимание метода Arrays.asList(Tarray) для примитивных типов

Я написал следующий код и был удивлен, увидев результат:

    Integer a = 211;
    int b = 211;

    int[] array = {210,211,212};

    System.out.println(Arrays.asList(array).contains(a));
    System.out.println(Arrays.asList(array).contains(b));

Выход:

false
false

Я нашел этот вопрос и некоторые другие вопросы, связанные с ним и узнал, что метод asList не загружает Autobox. Я проверил возвращенный тип в предварительном просмотре eclipse javadoc:

введите здесь описание изображения

Я не мог понять этот тип возврата. int[] - это объект, а не примитив, так что все в порядке. Я уверен, что не получу List<Integer> (что-то, чего я ожидал), но я не уверен, как использовать возвращаемую вещь. Мои вопросы:

    1. How exactly do I expect that list methods will work when I'm expecting an List of Integer and getting a List of int[] ?
    2. In case of Strings the return type is List of String and not List of String[]. What sort of implementation differences are there?
    3. What good is this method for primitives if things are so uncertain?

person ares    schedule 17.09.2014    source источник


Ответы (5)


Здесь, очевидно, 3 вопроса, поэтому давайте рассмотрим их один за другим:

  1. Как именно я ожидаю, что методы списка будут работать, когда я ожидаю список целых чисел и получаю список int[] ?

Что ж, методы List будут работать именно так, как ожидалось, List<T> — это список типов T. Здесь T — это int[], поэтому List<int[]> будет содержать массивы в качестве каждого элемента:

[{1, 2}, {3, 4}, {1, 6}]

Таким образом, get(i) вернет элемент ith. В случае Arrays.asList List содержит один элемент, а именно int[], поэтому:

int[] array = {210,211,212};
List<int[]> list = Arrays.asList(array);

Будет

[{210, 211, 212}]

И так

list.get(0)[0] == 210

В случае строк возвращаемый тип — это список строк, а не список строк []. Какие существуют различия в реализации?

String — это Object, не примитивный тип. Разница вытекает из этого.

  1. Что хорошего в этом методе для первобытных людей, если все так неопределенно?

Вещи не неопределенны. Этот метод приводит к определенному и предсказуемому поведению. Это просто не очень полезно для примитивов. Это (еще один) побочный эффект объединения системы типов Java с дженериками.

Обратите внимание, что в Java 8 преобразование int[] в List<Integer> очень просто:

List<Integer> list = Arrays.stream(array).
        boxed().
        collect(toList());
person Boris the Spider    schedule 17.09.2014
comment
Спасибо за новый пример Java 8 - person ares; 23.09.2014

Вы не получаете Lit или List (чего не может быть), вы получаете List массивов целых чисел.

Таким образом, ваш список не содержит 211, он содержит массив, который затем содержит 211.

Массив не "разворачивается" в список, он добавляется "как есть" во вновь созданный список.

So :

System.out.println(Arrays.asList(array).contains(array)); // Will return true
System.out.println(Arrays.asList(a).contains(a)); // Will return true
person Simone Gianni    schedule 17.09.2014

Это потому, что Arrays.asList() является вариативной универсальной функцией. Измени это,

int[] array = {210,211,212};

to

Integer[] array = { 210, 211, 212 };

И выход будет true и true.

person Elliott Frisch    schedule 17.09.2014

Arrays.asList принимает объекты в качестве параметров. Поскольку int[] является объектом, вы получаете список. Если вам нужен список целых чисел, вы должны сделать Arrays.asList(211,212,213).

person Nadir    schedule 17.09.2014

int[] array = {210,211,212};

Arrays.asList(array)

равно

List<int[]> asList = Arrays.asList(array); 

Сдача

int[] array = {210,211,212}; до Integer[] array = {210,211,212}; и все заработает. и равно List<Integer> asList = Arrays.asList(array);

person Prabhakaran Ramaswamy    schedule 17.09.2014