Java:ArrayList-如何检查索引是否存在?


111

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

我应该简单地get()检查一下值吗?还是应该等待例外?还有另一种方法吗?

更新资料

感谢您的回答,但是由于我仅在特定索引处添加内容,因此列表的长度不会向我显示可用的内容。


2
看一下Set,也许它更适合您的需求?
保罗·惠兰

3
然后,您将不得不get()检查null-尽管不要依赖异常。考虑HashTable改用java.sun.com/j2se/1.4.2/docs/api/java/util/Hashtable.html
Amarghosh,2010年

太棒了!! 我将使用HashTable感谢
ufk 2010年

Answers:


157

该方法arrayList.size() 返回列表中的项目数-因此,如果索引大于或等于,则该索引size()不存在。

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

10
这应该是“大于或等于size()”,因为它是从零开始的索引。
McDowell 2010年

1
还值得一提的是,要使这个原子化,您应该在锁定列表的同时执行size()检查和基于条件索引的相应查找。
亚当斯基2010年

3
请注意,我将此答案标记为正确的原因是,所有者(Amarghosh)在对我的问题的评论中回答了我的问题。HashTable将更好地满足我的需求。
ufk 2010年

如果您要在数组列表中用项目ID设置项目怎么办?例如 mylist.set(1,item1); mylist.set(3,item3); //跳过2我想HashMap更适合那种情况?
yeahman '16

如果我想在列表中做某事(如果索引已经存在的话),这还是不能令我满意的,否则我要准备一个新的列表index = 0,我list.size() == 0也将从这里开始。因此,我第一次检查它为true时,我将为该列表做准备。但是下一次使用该索引时,我的索引仍将保持不变index = 0,现在我应该在做某事时正在重新初始化列表中的该元素。第一种想法是在&&第二种条件下,list.get(index) == null但没有用,是为什么会有这样的问题
robertotomás16

68

虽然您有关于使用列表大小的许多建议,这些建议适用于具有线性条目的列表,但似乎没有人读过您的问题。

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

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

试试这个:

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

如果索引不存在,则在此处添加新条目。您可以更改它以执行其他操作。


2
谢谢您,需要这项技术用于单元测试是否存在数组索引。
Noumenon 2013年

11
切记要避免使用try/catch这种工作,它会使您的程序速度降低50%或更多。.错误检查在现有代码中增加了束缚,从而降低了速度。.最好避免在关键区域使用它。检查length在这种情况下,你能做的最好的事情,因为index总是会少那么length,旧index的将得到转移,并成为新index的,如果你remove他们,所以这就是为什么对于规则检查length始终正常工作。
SSpoke

1
@SSpoke ...虽然我同意,try / catch并不是一个“好的”答案;当列表稀疏时,它将解决该问题。我更喜欢使用数组的建议:Object [] ary; 下方或哈希。

12

这就是你所需要的...

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

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


3
并非总是如此,因为他可能希望ArrayList随着时间的推移而增长,而数组却做不到。
Coyote11年

7

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

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

如果您还担心index为负值,请使用以下命令

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

1
与几年前公认的答案相比,这如何提供任何价值?
罗勒·布尔克

2
我认为您认为这没有任何价值,但是我看到robertotomás对接受的答案发表了评论,假设他不太了解接受的答案。检查出来“用一个新列表,我将从索引= 0开始,我的list.size()== 0也开始。所以,我第一次检查它是正确的”,我决定发布一个单独的答案来帮助任何未来的混乱。
AamirR

6

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

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

最佳实践

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

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


1
如果array [8]不存在,则将遇到ArrayIndexOutOfBoundException。
Nitesh Kumar Anand


3

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


2

一种简单的方法:

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

1

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

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

或对于2Dimensional ArrayLists ...

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

1
列表没有.length它,list.size()但没什么大不了的,我一直这样搞糟,哈哈,我依靠编译器来指导我。您可能正在考虑原始数组
SSpoke

1
感谢您抓住这一点。容器的基数很容易忘记。
t3dodson

0

如果索引小于列表的大小,则该索引确实存在,可能具有null值。如果索引较大,则可以调用ensureCapacity() 以使用该索引。

如果要检查索引处的值是否为null,请致电get()


1
调用sureCapacity(int)不会增加List的大小,只会增加容量;即“潜在大小”,因此超出范围的索引查找仍将失败。
Adamski 2010年

另外,为什么要完全调用guaranteeCapacity(int)呢?例如,如果列表的当前大小为5,并且您要确定item#的值:100,000,000,这可能是一项非常昂贵的操作。
Adamski 2010年

我的意思是总是存在小于size()的索引,> = size()的索引不存在并且不能使用它们(==调用set()),直到列表变得足够大为止。仅仅调用sureCapacity确实不够,需要通过添加元素来更改大小。
德米特里(Dmitry)2010年

关于verifyCapacity(int)实际作用的错误解释。它与ArrayList大小无关。
Mohsen '02

0

您可以检查数组的大小。

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'
    }
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.