Сравните новые целочисленные объекты в вопросе ArrayList - PullRequest
7 голосов
/ 14 апреля 2010

Я храню целочисленные объекты, представляющие индекс объектов, которые я хочу отслеживать. Позже в моем коде я хочу проверить, соответствует ли индекс конкретного объекта одному из тех целых чисел, которые я сохранил ранее. Я делаю это путем создания ArrayList и создания нового целого числа из индекса цикла for:

ArrayList<Integer> courseselectItems = new ArrayList();

//Find the course elements that are within a courseselect element and add their indicies to the ArrayList
for(int i=0; i<numberElementsInNodeList; i++) {
    if (nodeList.item(i).getParentNode().getNodeName().equals("courseselect")) {
        courseselectItems.add(new Integer(i));
    }
}

Затем я хочу проверить, содержит ли ArrayList определенный индекс:

//Cycle through the namedNodeMap array to find each of the course codes
for(int i=0; i<numberElementsInNodeList; i++) {
    if(!courseselectItems.contains(new Integer(i))) {
        //Do Stuff
    }
}

У меня вопрос: когда я создам новое целое число с помощью new Integer(i), смогу ли я сравнить целые числа с помощью ArrayList.contains()? То есть, когда я создаю новый объект с использованием new Integer(i), будет ли он совпадать с ранее созданным объектом Integer, если значение int, использованное для их создания, будет одинаковым?

Надеюсь, я не сделал это слишком неясным. Спасибо за помощь!

Ответы [ 7 ]

18 голосов
/ 14 апреля 2010

Да, вы можете использовать List.contains(), поскольку он использует equals(), и Integer поддерживает это при сравнении с другими Integer с.

Также из-за автобокса вы можете просто написать:

List<Integer> list = new ArrayList<Integer>();
...
if (list.contains(37)) { // auto-boxed to Integer
  ...
}

Стоит отметить, что:

List list = new ArrayList();
list.add(new Integer(37));
if (list.contains(new Long(37)) {
  ...
}

будет всегда возвращать false, поскольку Integer не является Long. В какой-то момент это сбивает с толку большинство людей.

Наконец, попробуйте сделать ваши переменные, которые являются коллекциями Java типа интерфейса, а не конкретного типа, так:

List<Integer> courseselectItems = new ArrayList();

не

ArrayList<Integer> courseselectItems = new ArrayList();
4 голосов
/ 14 апреля 2010

У меня вопрос: когда я создаю новое целое число, используя новое целое число (i), смогу ли я сравнить целые числа, используя ArrayList.contains ()? То есть, когда я создаю новый объект, используя new Integer (i), будет ли он совпадать с ранее созданным объектом Integer, если значение int, использованное для их создания, одинаково?

Короткий ответ - да.

Длинный ответ ...

То есть, когда я создаю новый объект с использованием нового Integer (i), будет ли он таким же, как ранее созданный объект Integer, если значение int, использованное для их создания, совпадает?

Полагаю, вы имеете в виду "... это будет тот же экземпляр , что и ..." ? Ответ на этот вопрос no - вызов new всегда будет создавать отдельный экземпляр, отличный от предыдущего, даже если параметры конструктора идентичны.

Однако, несмотря на отдельную идентичность , эти два объекта будут иметь эквивалентное значение , т.е. вызов .equals () между ними вернет true.

Collection.contains ()

Оказывается, что иметь отдельные экземпляры эквивалентного значения ( .equals () возвращает true ) нормально. Метод .contains() находится в интерфейсе Collection. Описание Javadoc для .contains() гласит:

http://java.sun.com/javase/6/docs/api/java/util/Collection.html#contains(java.lang.Object)

логическое значение содержит (Объект o)

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

Таким образом, он будет делать то, что вы хотите.

Структура данных

Вам также следует подумать о правильной структуре данных.

Список только о сдерживании? порядок важен? Вы заботитесь о дубликатах? Поскольку список - это порядок, использование списка может означать, что ваш код заботится о порядке. Или что вам нужно поддерживать дубликаты в структуре данных.

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

1 голос
/ 14 апреля 2010

Я ставлю свой ответ в виде (проходного) теста, как пример того, как вы можете исследовать это самостоятельно. Не отговаривать вас от использования SO - это здорово - просто пытаться продвигать тесты характеристик .

import java.util.ArrayList;
import junit.framework.TestCase;

public class ContainsTest extends TestCase {
    public void testContains() throws Exception {
        ArrayList<Integer> list = new ArrayList<Integer>();
        assertFalse(list.contains(new Integer(17)));
        list.add(new Integer(17));
        assertTrue(list.contains(new Integer(17)));
    }
}
1 голос
/ 14 апреля 2010

Как упомянули Клетус и DJ, ваш подход будет работать.

Я не знаю контекст вашего кода, но если вас не интересуют конкретные индексы, рассмотрите также следующий стиль:

List<Node> courseSelectNodes = new ArrayList<Node>();

//Find the course elements that are within a courseselect element 
//and add them to the ArrayList
for(Node node : numberElementsInNodeList) {
    if (node.getParentNode().getNodeName().equals("courseselect")) {
        courseSelectNodes.add(node);
    }
}

// Do stuff with courseSelectNodes
for(Node node : courseSelectNodes) {
    //Do Stuff
}
1 голос
/ 14 апреля 2010

Да, потому что List.contains() использует метод equals() объекта для сравнения. И Integer.equals() сравнивает целочисленное значение.

1 голос
/ 14 апреля 2010

Короткий ответ - да, вы должны быть в состоянии сделать, например, ArrayList.contains(new Integer(14)), чтобы увидеть, есть ли 14 в списке. Причина в том, что Integer переопределяет метод equals, чтобы правильно сравнивать себя с другими экземплярами с тем же значением.

0 голосов
/ 14 апреля 2010

Да, автоматический бокс происходит, но это приводит к снижению производительности. Из вашего примера непонятно, почему вы хотите решить проблему таким способом.

Кроме того, из-за бокса создание класса Integer вручную является излишним.

...