【问题标题】:List of Longs how do you check if it contains a value?多头列表你如​​何检查它是否包含一个值?
【发布时间】:2012-09-17 06:30:07
【问题描述】:

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

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

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

在调试器中找到的 ListOfOrgIds

14057
821
18021

在调试器中找到的组织 ID

821
14057
18021

让我这么说吧,我正看着调试器,它告诉我 ListOfOrgIds.contains(i) 是假的……这显然是不真实的……

具体来说,看看 ListOfOrgs 的值...

821 确实在里面。为什么我在 contains 调用中得到错误消息?

【问题讨论】:

  • 你能再显示一些代码吗.. 因为这部分代码看起来是正确的.. 除非addThese.add()ListOfOrgIds 没有问题,我们不知道它们的外观..
  • 顺便说一句,您为什么要创建 LongList,即使您正在向它们添加 integer 值??
  • 应该没问题(尽管您可以使用相同的Long 两次)- 请展示一个简短但完整的程序来说明问题。
  • 你能给我们一个listOfOrgIdsorganizationIDs列表的例子吗?
  • @DmainEvent -> as you can see, 14057 is not in ListOfOrgIds .. 似乎没有.. 我们在两个列表中都看到了这个值.. 我们仍然没有了解您在做什么??能贴出完整的代码吗??

标签: java linked-list contains long-integer


【解决方案1】:

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

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

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

我不确定您要查找的确切操作,但您需要三种可能的操作:并集、交集和相对补集。有关它们的正式定义和维恩图,请参阅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));

【讨论】:

  • 不太关心受骗。到底什么是一套?某种哈希表?我不小心复制了相同的变量输出。这将在我更新我的帖子时反映出来。
  • 集合是另一种不允许重复的集合类型。把它想象成一个列表,但没有排序(这可能与您的情况无关)并且没有重复元素的可能性(在您的情况下可能不需要)。在这种情况下,它也快得多,因为对于任何 ListremoveAllretainAll 都是 O(n) = n^2,但 HashSetO(n ) = n。在幕后,它是使用一种哈希表实现的,但它本身并不是哈希表,因为它不像哈希表那样“映射”。
  • 另外,你是对我的回答投反对票的那个人吗?仅当解决方案在技术上不正确或未回答问题时才应使用否决票。请参阅this question 的答案,了解经验丰富的 SO 成员如何认为应该(也不应该)使用否决票。
  • 我投了反对票,因为我觉得你的帖子好像没有回答我的问题。虽然所有这些集合的东西都很有趣,但我有点困惑,为什么我的列表不会说某些东西不在其中,而它肯定不是……你甚至没有展示使用集合的等效示例。如果你编辑你的帖子,我会升级答案。
  • 我也不确定这是否能回答问题。该问题使用“List” API 作为初学者,即使它使用“Set”,当简单地“removeAll”方法就足够了时,你已经用太多信息压倒了操作。
【解决方案2】:

您遇到的问题是 java 不允许将原语加宽然后装箱,只能装箱然后加宽。这意味着 int 不能成为 Long,但 int 可以成为 Object(通过 Integer)。 this question 的最佳答案很好地描述了它。在这种情况下,您不会得到任何编译反馈,因为 contains 方法不使用 list 的类型参数,它接受任何对象。这在过去也让我多次感到困惑。

下面是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);
    }

}

【讨论】:

    猜你喜欢
    • 2013-02-08
    • 1970-01-01
    • 1970-01-01
    • 2012-08-14
    • 1970-01-01
    • 2011-10-08
    • 2015-07-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多