2010-04-13 50 views
7

我正在存储代表要跟踪的对象索引的整型对象。后来在我的代码中,我想检查特定对象的索引是否对应于我之前存储的那些整数之一。在ArrayList中比较新的整型对象问题

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包含特定的索引::我通过创建一个ArrayList,并从一个索引创建一个新的整数for循环这样

//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)创建一个新对象时,如果用于创建它们的int值相同,它是否与以前创建的Integer对象相同?

我希望我没有把它弄得太模糊。谢谢您的帮助!

+2

在旁注中,下面是一些值得了解整数和字符串的知识:http://www.devx.com/tips/Tip/42276 – 2010-04-14 01:30:04

回答

17

是的,您可以使用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(); 
+0

谢谢!是否有任何特定的原因,我想使我的变量的接口类型,而不是具体的类型? – ericso 2010-04-14 00:38:48

+1

@thechiman具体类型是一个实现细节。 *一般来说*参数,局部变量和类成员应该是接口,所以你不会被绑定到特定的实现。例如,它允许你在稍后的时间插入一个自定义的'List'实现,等等。 – cletus 2010-04-14 00:41:12

+0

如果'List'对类是完全私有的,这在其他地方是可见的,这并不重要。但是如果你以某种方式公开它(例如,包含列表的类有一个返回列表的方法),那么你一定要把它作为'List'而不是'ArrayList'返回。例如,您可能会后来决定“LinkedList”是一个更合适的实现。 – 2010-04-14 01:22:44

1

简短的回答是肯定的,你应该能够例如,查看ArrayList.contains(new Integer(14))是否在列表中。原因是Integer覆盖了equals方法,以便将其自身与具有相同值的其他实例进行正确比较。

1

是的,因为List.contains()使用equals()方法的对象进行比较。并且Integer.equals()不会比较整数值。

0

是的,自动装箱发生,但这会导致性能损失。从你的例子中不清楚你为什么要以这种方式解决问题。

此外,由于拳击,手工创建Integer类是多余的。

1

正如cletus和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 
} 
+0

我也喜欢。我可能会更改我的代码来执行此操作。谢谢! – ericso 2010-04-14 00:34:06

+0

我最终改变了我的代码来做类似的事情。谢谢! – ericso 2010-04-14 13:09:45

1

我把我的答案的形式一个(通过)测试,作为你如何自己研究的例子。不要阻止你使用SO--这很好 - 只是为了促销characterization tests

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))); 
    } 
} 
+0

是的,现在我想到了,我可以很容易地测试这个我的自我。嘿,我觉得很愚蠢。谢谢。 :) – ericso 2010-04-14 00:32:50

4

我的问题是,当我创建通过使用新的整数(I)的新的整数会我可以比较使用ArrayList.contains整数()?也就是说,当我使用新的Integer(i)创建一个新对象时,如果用于创建它们的int值相同,它是否与以前创建的Integer对象相同?

简短的回答是肯定的。

长的答案是...

也就是说,当我创建一个使用新的整数(I)的新对象,那将是一样先前创建的Integer对象,如果用于创建它们的int值是否相同?

我假定你的意思“......那将是相同实例为...”?答案是 - 调用new将始终创建与前一个实例不同的独立实例,即使构造器参数相同。

然而,尽管具有分离身份,这两个对象将具有等效值,即调用.equals()之间它们将返回true。

Collection.contains()

事实证明,具有等效值的单独的实例(.equals()返回真)是好的。 .contains()方法在Collection接口中。为.contains()的Javadoc描述说:

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))返回true。

因此,它会做你想做的。

数据结构

你也应该考虑是否有合适的数据结构。

列表仅仅是关于遏制?订单重要吗?你关心重复吗?由于列表是有序的,使用列表可能意味着您的代码关心排序。或者你需要在数据结构中保留重复项。但是,如果订单并不重要,如果您不想或不会有重复,并且如果您确实只使用此数据结构来测试是否包含特定值,则可能需要考虑然后是否应该使用Set代替。