2013-09-02 11 views
-1

Я использовал этот Прямодушный метод:Java, целые числа не уникальны, но как они сравниваются в коллекциях?

Collection<Integer> aCollection = Arrays.asList(1,2,3,4,5,6); 
    Integer a = new Integer(5); 

    if(aCollection.contains(a)) 
     System.out.println("aCollection contains 5"); 

Результата является "aCollection содержит 5". Целые числа не являются уникальными объектами всей системы, но в этом случае «5» в Collection<Integer> и new Integer(5) фактически ссылаются на один и тот же объект? Можно ли с уверенностью предположить, что любая коллекция будет вести себя таким образом при вызове .contains()?

Я не уверен, потому что при сравнении ссылки и значения по == результата:

3 == new Integer(3) 
new Integer(3) != new Integer(3) 
new Integer(3) == 3 
+3

Вы можете решить такого рода сомнения, просто посмотрев на исходный код. –

ответ

1

Он определен в JavaDoc:

boolean contains(Object o) 

Возвращает true, если этот набор содержит указанный элемент. Подробнее формально, возвращает true, если и только если эта коллекция содержит в наименее один элемент e такой, что (o==null ? e==null : o.equals(e)).

В словах: Если o является null, содержит вернется true, если коллекция содержит null элемента, в противном случае он будет возвращать true тогда и только тогда, когда есть элемент, который equals() тот, который вы ищете.

Каждый вызов new Integer(5) будет возвращать различные ссылки, но все объекты равны друг другу по equals() method of the Integer class:

Сравнивает этот объект с указанным объектом. Результат true, если и только если аргумент не null и является объектом Integer, то содержит то же значение int как этот объект.

+0

OK, новый Integer (3)! = new Integer (3) и (новое целое число (3)). Равен (новое целое число (3)). Коллекция сравнивается с равными. – user2622016

5

contains не сравнится по ссылке. new Integer(50000) отличается от другого звонка на new Integer(50000). Однако firstInt.equals(new Integer(50000)) вернет true, следовательно, содержащийся будет работать. Я использую более высокие цифры, поскольку интернирование может происходить с более низкими.

0-127 будет помещен в фиксированный пул при выполнении бокса , но не при явном создании новых объектов, поэтому у вас будет такая же ссылка на одно и то же значение, но выше у вас нет гарантии какого-либо интернирования , а ссылки могут быть разными объектами Integer для одного и того же значения. Integer.valueOf( будет пытаться, если это необходимо, проходить стажировку, а именно всегда в пределах [-128, 128) и без указания для или вне интернирования вне этого диапазона.

Можно ли с уверенностью предположить, что любая коллекция будет вести себя таким образом при вызове .contains()?

Можно предположить, что .contains(Object o) вернется trueтогда и только тогда, когда один или более членов удовлетворяет коллекции thatmember.equals(o), или если o имеет нулевое значение, и есть по крайней мере один null член.

Технически:

Возвращает true, если этот набор содержит указанный элемент. Подробнее формально, возвращает true, если и только если эта коллекция содержит в наименее один элемент e такой, что (o==null ? e==null : o.equals(e)).

+0

«_0-127 будет помещен в фиксированный пул, поэтому вы будете иметь одинаковую ссылку на одно и то же значение ...» «Не когда вы явно вызываете« новое целое число (5) ». – jlordo

+0

@jlordo ", но над этим у вас нет гарантии какого-либо интернирования, и ссылки могут быть разными". Теперь лучше? – hexafraction

+0

Я отредактировал свой комментарий, пока не совсем прав. У вас есть противоречие: «_0-127 будет помещен в фиксированный пул, поэтому вы будете иметь одинаковую ссылку на одно и то же значение ... и ссылки могут быть разными.» « – jlordo

0

.contains() коллекции вызывает метод .equals() внутри страны.

В вашем случае вы используете объект Integer. И Integer object .equals() может возвращать true во всех случаях, которые вы указали.

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

Теперь для коллекции

Collection<Person> aCollection = Arrays.asList(b,c,d); 
    Person a = new Person("Abhishek"); 

может возвращать ложь. потому что вы не переопределили метод .equals() в вашем классе Person

0

Autoboxing - это автоматическое преобразование, которое компилятор Java делает между примитивными типами и соответствующими классами обертки объектов. Например, преобразование int в Integer, double в Double и т. Д. Если преобразование идет другим путем, это называется распаковкой.

http://docs.oracle.com/javase/tutorial/java/data/autoboxing.html