【问题标题】:Good way to store unique integers存储唯一整数的好方法
【发布时间】:2012-07-01 22:11:56
【问题描述】:

我的问题是: 有什么方法可以快速确定一个数字是否包含在 Collection 中,以了解是否将其添加到集合中并保持唯一性。如果我能提供帮助,我宁愿不遍历列表。

我有一个名为numberListList<Integer>。我希望它存储唯一的整数,并且永远不允许添加重复项。我想做这样的事情:

private void add(int number) {
  if (!numberList.contains(number)) {
    numberList.add(number);
  }
}

但这显然行不通,因为numberList 包含Integer 对象的列表,因此无论数量多少,每个对象都是唯一的对象。

谢谢!

【问题讨论】:

  • 我认为contains(...)方法使用对象的equals(...)方法来查看它是否被集合持有,所以你上面的方法也应该防止重复。
  • 嗯,也许我的代码有其他问题,这会产生意想不到的结果。感谢您的提示!
  • 如果你的代码和我的一样,那么总是有其他问题!如果您需要帮助找到它,请回来提供更多信息!

标签: java collections unique


【解决方案1】:

一种是将整数存储在Set<Integer> 中,例如HashSet<Integer>。集合不允许重复。

编辑
此外,集合的 contains(...) 方法使用对象的 equals(...) 方法来查看它是否由集合持有,因此如果您需要使用 List 作为集合,上述方法也将防止重复.自己测试一下,你会发现是这样的。

例如:

  List<Integer> numberList = new ArrayList<Integer>();
  int[] myInts = {1, 1, 2, 3, 3, 3, 3, 4};
  for (int i : myInts) {
     if (!numberList.contains(i)) {
        numberList.add(i);
      }
  }

  System.out.println(numberList);

将返回:[1, 2, 3, 4]

此外,HashSet 的一个可能问题是它们没有排序,因此如果排序很重要,您需要考虑使用其他种类的有序 Set。

【讨论】:

  • 出于好奇,您认为哪种实现会更快?让Set 处理重复项或在添加之前在列表上使用contains 会更快吗?
  • @kentcdodds:我相信 HashSet 会更快,因为散列是一种非常快速的操作,但我不能 100% 保证,因为我从未研究过算法的大 O。但是请稍等,毫无疑问,其中一位计算机科学家很快就会回答这个问题。
  • 当然使用 HashSet 更快。也可以避免 if (!contains) add.. 模式,因为 HashSet.add 会在内部检查这一点并返回 true,如果已将新元素添加到集合中。
【解决方案2】:

最紧凑的形式不是BitSet吗?它在存储方面是有效的,因为它会无限扩展。它也不会不必要地使用存储空间。

您是否在多线程环境中工作?如果是这样,还有其他可能更好/更有效的结构。

【讨论】:

  • 你找到我了!这是一个多线程环境,这就是我这样做的原因。我想检查一个线程是否已经添加了号码。
  • 在这种情况下,您几乎可以肯定在寻找ConcurrentHashMap,可能包含在使用newSetFromMap 派生的集合中,但如果您愿意,您可以随时将Boolean.TRUE 添加到Map
  • BitSet 对于小而密集的数字集非常有效。但是new BitSet().add(Integer.MAXVALUE); 已经分配了 268MB。所以要谨慎使用。
  • @Arne - 是的,但只要该元素存在于集合中,它就会一直分配。当然,并不是对每个用例都有用,但在某些情况下,不会发生进一步的分配,而且常数因子极低,这使得它非常有吸引力。
猜你喜欢
  • 1970-01-01
  • 2015-02-22
  • 1970-01-01
  • 1970-01-01
  • 2019-12-17
  • 1970-01-01
  • 1970-01-01
  • 2014-03-31
  • 2023-03-17
相关资源
最近更新 更多