Longs列表如何检查它是否包含值?

时间:2012-09-25 17:25:03

标签: java linked-list contains long-integer

温馨的一天。

我正在尝试检查long的列表是否不包含某个值。虽然我知道某个链表中不存在一个值,但似乎永远不会满足条件......

for(int i : organizationIDs){
    if(!ListOfOrgIds.contains(Long.valueOf(i))){
        addThese.add(new Long(i));
    }
}

我基本上在寻找orgID数组中不存在的值,如果它不存在,请将其添加到addThese链表中...我是否错过了Long的一些细微差别我应该知道?

调试器中的ListOfOrgIds

14057
821
18021

在调试器中找到的OrganizationID

821
14057
18021

让我这样说吧,我正在调试调试器,它正在告诉我 ListOfOrgIds.contains(i)  是假的......这显然是不真实的...... enter image description here

具体来说,请查看ListOfOrgs ...

的值

enter image description here

821确实在那里。为什么我在包含电话上得到错误?

2 个答案:

答案 0 :(得分:2)

你遇到的问题是java不允许扩展基元然后加框,只加框然后加宽。这意味着int不能成为Long,但int可以成为Object(通过Integer)。 this question的最佳答案描述得相当不错。在这种情况下,您不会收到任何编译反馈,因为contains方法不使用list的type参数,它接受任何对象。这也让我在过去多次抓到了。

下面是SSCCE,其中显示了您获得的结果以及一个有效的示例。请注意,所需要的只是将int显式地转换为long。

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class BoxingTest {

    public static void main(String[] args) throws Exception {

        List<Integer> intList = Arrays.asList(new Integer[]{14, 24, 69});
        List<Long> sourceLongList = Arrays.asList(new Long[]{14L, 17L});

        List<Long> resultsList;
        /* Test as in question code */
        resultsList = new ArrayList<Long>();
        for(int i : intList){
            if(!sourceLongList.contains(i)){
                resultsList.add(new Long(i));
            }
        }
        printList(resultsList);

        /* Can't box then widen, so cast */
        resultsList = new ArrayList<Long>();
        for(int i : intList){
            if(!sourceLongList.contains((long)i)){
                resultsList.add(new Long(i));
            }
        }
        printList(resultsList);

    }

    private static <T> void printList(List<T> values){
        StringBuilder contents = new StringBuilder();
        for(T value : values){
            contents.append(value);
            contents.append(" ");
        }
        System.out.println("List contains: " + contents);
    }

}

答案 1 :(得分:1)

我想说的第一点是,使用Set似乎更好,因为它不允许重复元素。换句话说,做:

Set<Long> ids = new HashSet<Long>();
ids.add(Long.valueOf(1));
ids.add(Long.valueOf(1));
System.out.println(ids.size());

将打印1,而不是像2那样List

我不确定您正在寻找的确切操作,但您可能需要三种:联合,交集和相对补充。有关其正式定义和维恩图,请参阅this Wikipedia section on the Set page

<强>联盟

结果:AB中的所有元素都位于C

执行此操作:

Set<Long> a = ... ;
Set<Long> b = ... ;
Set<Long> c = new HashSet<Long>(a);
c.addAll(b);

<强>交叉口

结果:只有AB中的元素都位于C

执行此操作:

Set<Long> a = ... ;
Set<Long> b = ... ;
Set<Long> c = new HashSet<Long>(a);
c.retainAll(b);

相对补充

结果:C将包含A中的所有元素,但B

中的元素除外

执行此操作:

Set<Long> a = ... ;
Set<Long> b = ... ;
Set<Long> c = new HashSet<Long>(a);
c.removeAll(b);

此外,List转换为Set

List<Long> idsAsList = ... ;
Set<Long> idsAsSet = new HashSet<Long>(idsAsList);

要将数组转换为Set,您必须采取不同的做法,具体取决于您是long[]还是Long[](请注意上限)。对于long[],您必须手动复制:

long[] idsAsArray = ... ;
Set<Long> idsAsSet = new HashSet<Long>();
for (long l : idsAsArray) {
    idsAsSet.add(Long.valueOf(l));
}

如果是Long[],您可以使用Arrays.asList

Long[] idsAsArray = ... ;
Set<Long> ids = new HashSet<Long>(Arrays.asList(idsAsArray));