java: ArrayList - como posso verificar se existe um índice?


111

Estou usando ArrayList<String>e adiciono dados em índices específicos, como posso verificar se existe um índice específico?

Devo simplesmente get()verificar o valor? Ou devo esperar por uma exceção? Existe outra maneira?

Atualizar

Obrigado por suas respostas, mas porque estou apenas adicionando coisas em índices específicos, o comprimento da lista não vai me mostrar quais estão disponíveis.


2
Dê uma olhada em um Set, talvez seja mais adequado para o que você precisa?
Paul Whelan

3
Então você terá que get()verificar null- não dependa de exceções. Considere o uso de uma HashTablevez java.sun.com/j2se/1.4.2/docs/api/java/util/Hashtable.html
Amarghosh

impressionante!! Vou usar o HashTable, obrigado
ufk

Respostas:


159

O método arrayList.size() retorna o número de itens na lista - portanto, se o índice for maior ou igual a size(), ele não existe.

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

10
Isso deve ser "maior ou igual a size()", pois é um índice baseado em zero.
McDowell

1
Também vale a pena mencionar que, para tornar isso atômico, você provavelmente deve executar a verificação size () e a consulta baseada no índice condicional correspondente enquanto bloqueia a lista.
Adamski

3
Observe que eu marquei essa resposta como a correta porque o proprietário (Amarghosh) respondeu minha pergunta em um comentário à minha pergunta. O HashTable atenderá às minhas necessidades muito melhor.
ufk

e se você estiver definindo itens na arraylist com o ID do item? ex. mylist.set (1, item1); mylist.set (3, item3); // pulando 2 Eu acho que o HashMap é mais adequado para esse cenário?
yeahman

isso não me satisfaz ... se eu quiser fazer algo na lista se o índice já estiver lá, mas caso contrário, prepará-lo ... com uma nova lista que vou começar index = 0e minha list.size() == 0também. então a primeira vez que verificar será verdade e prepararei a lista para fazer coisas. mas da próxima vez nesse índice, meu índice ainda estará index = 0e agora estou reinicializando esse elemento na lista quando deveria estar fazendo coisas. O primeiro pensamento é para &&uma segunda condição como list.get(index) == nullmas que não está funcionando é por que há perguntas como esta
roberto tomás

69

Embora você tenha uma dúzia de sugestões sobre como usar o tamanho de sua lista, que funcionam para listas com entradas lineares, ninguém pareceu ter lido sua pergunta.

Se você adicionar entradas manualmente em índices diferentes, nenhuma dessas sugestões funcionará, pois você precisa verificar um índice específico.

Usar if (list.get (index) == null) também não funcionará, pois get () lança uma exceção em vez de retornar null.

Experimente isto:

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

Aqui, uma nova entrada é adicionada se o índice não existir. Você pode alterá-lo para fazer algo diferente.


2
Obrigado, essa técnica necessária para testar a unidade se os índices de array existem.
Noumenon,

11
Lembre-se de evitar o uso try/catchpara este tipo de trabalho, pois isso tornará seu programa mais lento em 50% ou talvez mais .. a verificação de erros adiciona como uma correia ao seu código existente para desacelerá-lo .. melhor evitá-lo em áreas críticas. Verificar lengthneste caso é a melhor coisa que você pode fazer, uma vez que o indexsempre será menor que o lengthantigo indexserá alterado e se tornará novo indexse você removeos fizer, então é por isso que a verificação de regra lengthsempre funcionará.
SSpoke de

1
@SSpoke ... Embora eu concorde, try / catch está longe de ser uma resposta 'boa'; ele resolverá o problema quando a lista for esparsa. Prefiro a sugestão de usar um array: Object [] ary; abaixo ou um hash.
será

12

Isto é o que você precisa ...

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

Por que não usar um array simples e antigo? O acesso indexado a uma lista é um cheiro de código, eu acho.


3
Nem sempre, já que ele pode querer que a ArrayList cresça com o tempo, e isso uma matriz não pode fazer.
Coyote21 de

7

Normalmente eu apenas verifico se o índice é menor que o tamanho do array

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

Se você também está preocupado com o índice ser um valor negativo, use o seguinte

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

1
Como isso fornece algum valor em relação à Resposta aceita de vários anos atrás?
Basil Bourque

2
Acho que na sua opinião não tem valor, mas vi um comentário de roberto tomás sobre a resposta aceita, supondo que ele não entendeu bem a resposta aceita. confira "com uma nova lista vou começar em index = 0 e meu list.size () == 0 também. então a primeira vez que verificar será verdade" Decidi postar uma resposta separada para ajudar qualquer confusão futura.
AamirR

6

Em relação à sua atualização (que provavelmente deve ser outra pergunta). Você deve usar uma matriz desses objetos em vez de uma ArrayList, para que possa simplesmente verificar o valor de null:

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

Melhor prática

Se você não tiver centenas de entradas em seu array, deve considerar organizá-lo como uma classe para se livrar dos números mágicos 3,8 etc.

O fluxo de controle usando exceção é uma prática ruim.


1
Se array [8] não existir, você encontrará ArrayIndexOutOfBoundException.
Nitesh Kumar Anand


3

Você pode verificar o tamanho de um ArrayListusando o size()método. Isso retornará o índice máximo +1


2

uma maneira simples de fazer isso:

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

1

Teste rápido e sujo para verificar se um índice existe ou não. em sua lista de substituição de implementação Com sua lista, você está testando.

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

ou para ArrayLists 2D ...

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

1
Lista não tem .length, list.size()mas não é grande coisa Eu estrago assim o tempo todo haha ​​Eu confio no compilador para me guiar nisso. Você provavelmente estava pensando em matrizes primitivas
SSpoke de

1
Obrigado por pegar isso. A cardinalidade dos contêineres pode ser fácil de esquecer.
t3dodson

0

Se o seu índice for menor que o tamanho da sua lista, ele existe, possivelmente com nullvalor. Se o índice for maior, você pode chamarensureCapacity() para poder usar esse índice.

Se você quiser verificar se um valor em seu índice é nullou não, chameget()


1
A chamada de verifyCapacity (int) não aumentará o tamanho da Lista, apenas a capacidade; ou seja, "tamanho potencial", portanto, as pesquisas de índice fora dos limites ainda falham.
Adamski

Além disso, por que chamar sureCapacity (int)? Pode ser uma operação incrivelmente cara se, por exemplo, o tamanho atual da lista for 5 e você quiser determinar o valor do item nº: 100.000.000.
Adamski

Eu quis dizer que índices menores que size () sempre existem, aqueles que são> = size () não e não podem ser usados ​​(== call set ()) até que a lista fique grande o suficiente. Na verdade, chamar o verifyCapacity não é suficiente, é preciso alterar o tamanho adicionando elementos.
Dmitry

Explicação errada sobre o que o verifyCapacity (int) realmente faz. Não faz nada com o tamanho de ArrayList.
Mohsen

0

Você pode verificar o tamanho da matriz.

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'
    }
}
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.