【问题标题】:ArrayList - how can I check if an index exists?ArrayList - 如何检查索引是否存在?
【发布时间】:2011-01-09 01:29:58
【问题描述】:

我正在使用ArrayList<String>,我在特定索引处添加数据,如何检查特定索引是否存在?

我应该简单地get() 并检查值吗?还是我应该等待异常? 还有其他方法吗?

更新:感谢您的回答,但由于我只在特定索引处添加内容,因此列表的长度不会显示哪些可用。

【问题讨论】:

标签: java arraylist


【解决方案1】:

方法arrayList.size()returns列表中的项目数——所以如果索引大于等于size(),则不存在。

if(index >= myList.size()){
  //index does not exists
}else{
 // index exists
}

【讨论】:

  • 这应该是“大于或等于size()”,因为它是一个从零开始的索引。
  • 另外值得一提的是,要使这个原子化,您可能应该在锁定列表的同时执行 size() 检查和相应的基于条件索引的查找。
  • 请注意,我将此答案标记为正确是因为所有者(Amarghosh)在对我的问题的评论中回答了我的问题。 HashTable 将更好地满足我的需求。
  • 如果你在arraylist中设置项目的ID怎么办?前任。 mylist.set(1, item1); mylist.set(3, item3); //skipping 2 我猜HashMap更适合那个场景?
  • 这不太让我满意..如果我想在索引已经存在的情况下在列表中做某事,否则要准备它..我将开始使用新列表在index = 0 和我的list.size() == 0 也是。所以我第一次检查它会是真的&我会准备好做事情的清单。但是下一次在那个索引处,我的索引仍然是index = 0,现在我正在重新初始化列表中的那个元素,当我应该做的事情时。第一个想法是&&list.get(index) == null 这样的第二个条件,但不起作用是为什么会有这样的问题
【解决方案2】:

虽然您收到了十几个关于使用列表大小的建议,这些建议适用于具有线性条目的列表,但似乎没有人阅读您的问题。

如果您在不同的索引处手动添加条目,这些建议都不起作用,因为您需要检查特定索引。

使用 if ( list.get(index) == null ) 也不起作用,因为 get() 会抛出异常而不是返回 null。

试试这个:

try {
    list.get( index );
} catch ( IndexOutOfBoundsException e ) {
    list.add( index, new Object() );
}

如果索引不存在,则在此处添加一个新条目。你可以改变它来做一些不同的事情。

【讨论】:

  • 谢谢,需要这种技术来单元测试数组索引是否存在。
  • 记住要避免在这种工作中使用try/catch,它会使你的程序减慢 50% 甚至更多.. 错误检查就像是现有代码的一条带子,可以减慢它的速度。 . 最好在关键区域避免它。在这种情况下检查length 是你能做的最好的事情,因为index 总是比length 少,旧的index 会被转移并变成新的index remove 他们,这就是为什么检查 length 的规则总是有效的原因。
  • @SSpoke ...虽然我同意,但 try/catch 远非“好”的答案;当列表稀疏时,它将解决问题。我更喜欢使用数组的建议:Object[] ary;下面或哈希。
  • 使用异常来进行流量控制,如本例所示,这是一种反模式softwareengineering.stackexchange.com/questions/189222/…
【解决方案3】:

这就是你需要的……

public boolean indexExists(final List list, final int index) {
    return index >= 0 && index < list.size();
}

为什么不使用普通的旧数组?我认为对 List 的索引访问是一种代码味道。

【讨论】:

  • 并非总是如此,因为他可能希望 ArrayList 随着时间的推移而增长,而数组无法做到这一点。
【解决方案4】:

通常我只是检查索引是否小于数组大小

if (index < list.size()) {
    ...
}

如果您还担心索引是负值,请使用以下

if (index >= 0 && index < list.size()) {
    ...
}

【讨论】:

  • 与几年前的 accepted Answer 相比,这如何提供任何价值?
  • 我猜你认为它没有提供任何价值,但我看到了 roberto tomás 对接受的答案的评论,假设他不太理解接受的答案。检查一下“我将从 index = 0 和我的 list.size() == 0 开始的新列表。所以我第一次检查它会是真的”我决定发布一个单独的答案来帮助任何未来的混乱。
【解决方案5】:

关于您的更新(这可能应该是另一个问题)。 您应该使用这些对象的数组而不是 ArrayList, 所以你可以简单地检查 null 的值:

Object[] array = new Object[MAX_ENTRIES];
..
if ( array[ 8 ] == null ) {
   // not available
}
else {
   // do something
}

最佳实践

如果您的数组中没有数百个条目,则应考虑将其组织为一个类,以摆脱魔术数字 3,8 等。

使用异常的控制流是不好的做法。

【讨论】:

  • 如果array[8]不存在,会遇到ArrayIndexOutOfBoundException。
【解决方案6】:

从 Java 9 开始,有一种检查索引是否属于数组的标准方法 - Objects#checkIndex()

List<Integer> ints = List.of(1,2,3);
System.out.println(Objects.checkIndex(1,ints.size())); // 1
System.out.println(Objects.checkIndex(10,ints.size())); //IndexOutOfBoundsException

【讨论】:

【解决方案7】:

这是为 Kotlin 开发人员准备的:

if (index in myList.indices) {
  // index is valid
}

其他解决方案:

if (index in 0..myArray.lastIndex) {
  // index is valid
}
if (index >= 0 && index <= myList.lastIndex) {
  // index is valid
}
// Note: elements of the list should be non-null
if (myList.getOrNull(index) != null) {
  // index is valid
}
// Note: elements of the list should be non-null
myList.getOrNull(index)?.let { element ->
  // index is valid; use the element
}

【讨论】:

    【解决方案8】:

    您可以使用size() 方法检查ArrayList 的大小。这将返回最大索引 +1

    【讨论】:

      【解决方案9】:

      你可以检查数组的大小。

      package sojava;
      import java.util.ArrayList;
      
      public class Main {
          public static Object get(ArrayList list, int index) {
              if (list.size() > index) { return list.get(index); }
              return null;
          }
      
          public static void main(String[] args) {
              ArrayList list = new ArrayList();
              list.add(""); list.add(""); list.add("");        
              System.out.println(get(list, 4));
              // prints 'null'
          }
      }
      

      【讨论】:

        【解决方案10】:

        对索引是否存在的快速而肮脏的测试。在你的实现中用你正在测试的列表替换列表。

        public boolean hasIndex(int index){
            if(index < list.size())
                return true;
            return false;
        }
        

        或者对于二维数组列表...

        public boolean hasRow(int row){
            if(row < _matrix.size())
                return true;
            return false;
        }
        

        【讨论】:

        • 列表没有.length,它有list.size(),但这没什么大不了的,我总是这样搞砸哈哈,我依靠编译器来指导我。您可能正在考虑原始数组
        • 感谢您的关注。容器基数很容易忘记。
        【解决方案11】:

        一个简单的方法:

        try {
          list.get( index ); 
        } 
        catch ( IndexOutOfBoundsException e ) {
          if(list.isEmpty() || index >= list.size()){
            // Adding new item to list.
          }
        }
        

        【讨论】:

          【解决方案12】:

          如果您的索引小于列表的大小,则它确实存在,可能带有null 值。如果索引更大,那么您可以调用ensureCapacity() 来使用该索引。

          如果您想检查索引中的值是否为null,请致电get()

          【讨论】:

          • 调用 ensureCapacity(int) 不会增加 List 的大小,只会增加容量;即“潜在大小”,因此超出范围的索引查找仍然会失败。
          • 另外,为什么要调用 ensureCapacity(int) 呢?例如,如果列表的当前大小为 5,并且您想确定 item#: 100,000,000 的值,这可能是一个非常昂贵的操作。
          • 我的意思是小于 size() 的索引始终存在,那些 >= size() 的索引不存在,并且在列表变大之前不能使用它们(== 调用 set())足够的。调用 ensureCapacity 确实不够,需要通过添加元素来改变大小。
          • 关于 ensureCapacity(int) 实际作用的错误解释。它与 ArrayList 大小无关。
          猜你喜欢
          • 2021-07-22
          • 2013-03-21
          • 2016-03-21
          • 1970-01-01
          • 1970-01-01
          • 2012-11-30
          • 2015-09-16
          • 2016-09-19
          • 2021-01-15
          相关资源
          最近更新 更多