Поведение функции «содержит» в Java - PullRequest
1 голос
/ 03 января 2012

Я отлаживаю свой код, и похоже, что встроенная функция contains не работает должным образом в моем случае. Посмотрите:

List<Integer[]> allVariables = new ArrayList<Integer[]>();
Integer[] cols = {1};

Список содержит значения:

[0] = Integer[1] => {1}
[1] = Integer[4] => {1,2,3,4}

Итак, следующее выражение IF должно быть TRUE, но оно ложно:

if (allVariables.contains(cols[0])) {
    //...
}

В чем проблема?

Ответы [ 8 ]

2 голосов
/ 03 января 2012

Массивы являются изменяемыми и, как таковые, равны, только если они являются одним и тем же массивом. (Не на основе их содержимого) Если вы хотите сравнить содержимое, вам может понадобиться использовать List<Integer>

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

Попробуйте следующее

public static void main(String... args) {
    List<List<Integer>> allVariables = new ArrayList<List<Integer>>();
    allVariables.add(Arrays.asList(1));
    allVariables.add(Arrays.asList(1,2,3,4));

    testContains(allVariables, 1);
    testContains(allVariables, 1, 2);
    testContains(allVariables, 1, 2, 3);
    testContains(allVariables, 1, 2, 3, 4);
}

private static void testContains(List<List<Integer>> allVariables, Integer... ints) {
    List<Integer> intList = Arrays.asList(ints);
    System.out.println("allVariables contains " + intList +
                       " is " + allVariables.contains(intList));
}

печать

allVariables contains [1] is true
allVariables contains [1, 2] is false
allVariables contains [1, 2, 3] is false
allVariables contains [1, 2, 3, 4] is true
2 голосов
/ 03 января 2012

У вас есть список Integer[] вместо List<Integer>. Вот в чем проблема. Когда вы делаете сравнение, вы спрашиваете, равняется ли Integer x = 1 Integer[] y = {1};

2 голосов
/ 03 января 2012

Список содержит Integer[] объектов, поэтому, если вы спросите его, содержит ли он cols, он вернет true.Тем не менее, он не содержит каждый из отдельных элементов массива.

Если вы хотите использовать содержит для каждого из элементов этих массивов, вы должны добавить каждый элемент массива в список вместо самого массива(например, используя Collections#addAll)

1 голос
/ 03 января 2012

cols[0] - это Integer, а не Integer[], который является типом элемента вашего списка.Так что можно ожидать, что contains не найдет соответствия.Одноэлементный массив не равен отдельному элементу - это разные объекты разных типов.

1 голос
/ 03 января 2012

http://docs.oracle.com/javase/1.5.0/docs/api/java/util/Collection.html#contains%28java.lang.Object%29

Ваша коллекция содержит массивы, а не целые числа. Так что содержит проверки методов для массивов. Ваша проверка должна быть if (allVariables.contains (cols)) или, если вы хотите проверить целочисленное значение, вам нужно выполнить итерацию по всем массивам в списке и последовательно проверять их.

1 голос
/ 03 января 2012

Contains будет искать только тот тип, который на самом деле представляет список.

Итак, если у вас есть список Integer[], вы не сможете когда-либо передать int и получить true результат (поскольку int не может быть null).

Чтобы сделать это, вам нужно выполнить глубокий поиск самостоятельно:

for(Integer[] arr : allVariables) {
    for(Integer i : arr) {
        if(i != null && i.equals(searchValue)) return true;
    }
}
return false;
1 голос
/ 03 января 2012

Содержит поиск объектов по ссылке, а не по значениям. У вас есть два разных массива с одинаковым значением - {1}

0 голосов
/ 03 января 2012

В java cols [0] очень отличается от cols. В C / C ++ они одинаковы. По cols [0] вы ссылаетесь на первый элемент в Integer []. Попробуйте напечатать значения cols [0] и cols, и вы сможете найти разницу.

Поведение, демонстрируемое java api, идеально в вашем случае. Так как cols [0] всегда будет возвращать 1, что у вас есть в вашем Integer []. Но 1 как целое число недоступно в arraylist. Таким образом, это всегда дает ложь.

...