java: ArrayList - làm cách nào để kiểm tra xem chỉ mục có tồn tại không?


111

Tôi đang sử dụng ArrayList<String>và tôi thêm dữ liệu ở các chỉ số cụ thể, làm cách nào để kiểm tra xem chỉ mục cụ thể có tồn tại hay không?

Tôi có nên đơn giản get()và kiểm tra giá trị không? Hay tôi nên đợi một ngoại lệ? Có cách nào khác không?

Cập nhật

Cảm ơn câu trả lời của bạn, nhưng vì tôi chỉ thêm nội dung ở các chỉ số cụ thể, độ dài của danh sách sẽ không hiển thị cho tôi những thứ có sẵn.


2
Hãy xem một Bộ có lẽ nó phù hợp hơn với những gì bạn cần?
Paul Whelan

3
Sau đó, bạn sẽ phải get()kiểm tra null- tuy nhiên, đừng dựa vào các trường hợp ngoại lệ. Xem xét sử dụng một HashTablethay java.sun.com/j2se/1.4.2/docs/api/java/util/Hashtable.html
Amarghosh

tuyệt vời!! Tôi sẽ sử dụng HashTable, cảm ơn
ufk

Câu trả lời:


157

Phương thức này arrayList.size() trả về số lượng các mục trong danh sách - vì vậy nếu chỉ mục lớn hơn hoặc bằng size()thì nó không tồn tại.

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

10
Giá trị đó phải là "lớn hơn hoặc bằng size()" vì nó là chỉ số dựa trên số không.
McDowell

1
Cũng đáng nói rằng để tạo nguyên tử này, bạn có thể nên thực hiện kiểm tra kích thước () và tra cứu dựa trên chỉ mục có điều kiện tương ứng trong khi khóa danh sách.
Adamski

3
xin lưu ý rằng tôi đánh dấu câu trả lời này là đúng vì chủ sở hữu (Amarghosh) đã trả lời câu hỏi của tôi trong một nhận xét cho câu hỏi của tôi. HashTable sẽ đáp ứng nhu cầu của tôi tốt hơn nhiều.
ufk

điều gì sẽ xảy ra nếu bạn đang đặt các mục trong danh sách mảng với ID của mục? Ví dụ. mylist.set (1, item1); mylist.set (3, item3); // bỏ qua 2 Tôi đoán HashMap phù hợp hơn với kịch bản đó?
yeahman

điều này không làm tôi hoàn toàn hài lòng .. nếu tôi muốn làm điều gì đó trong danh sách nếu chỉ mục đã ở đó, nhưng nếu không để chuẩn bị cho nó .. với một danh sách mới, tôi sẽ bắt đầu index = 0và cả của tôi list.size() == 0nữa. vì vậy lần đầu tiên tôi kiểm tra nó sẽ đúng và tôi sẽ chuẩn bị danh sách để làm những việc. nhưng lần tiếp theo tại chỉ mục đó, chỉ mục của tôi sẽ vẫn còn index = 0và bây giờ tôi đang khởi tạo lại phần tử đó trong danh sách khi tôi được cho là đang thực hiện công việc. Ý nghĩ đầu tiên là đến &&điều kiện thứ hai như thế list.get(index) == nullnhưng điều đó không hoạt động là lý do tại sao có những câu hỏi như thế này
roberto tomás

69

Trong khi bạn nhận được hàng tá gợi ý về việc sử dụng kích thước danh sách của mình, phù hợp với các danh sách có mục nhập tuyến tính, dường như không ai đọc câu hỏi của bạn.

Nếu bạn thêm các mục theo cách thủ công tại các chỉ mục khác nhau thì không có đề xuất nào trong số này sẽ hoạt động, vì bạn cần kiểm tra một chỉ mục cụ thể.

Sử dụng if (list.get (index) == null) cũng sẽ không hoạt động, vì get () ném một ngoại lệ thay vì trả về null.

Thử cái này:

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

Ở đây, một mục mới được thêm vào nếu chỉ mục không tồn tại. Bạn có thể thay đổi nó để làm điều gì đó khác biệt.


2
Cảm ơn bạn, cần kỹ thuật này để kiểm tra đơn vị xem chỉ số mảng có tồn tại hay không.
Noumenon

11
Hãy nhớ tránh sử dụng try/catchcho loại công việc này, nó sẽ làm chậm chương trình của bạn 50% hoặc có thể hơn .. kiểm tra lỗi thêm như một dây đeo vào mã hiện có của bạn để làm chậm nó .. tốt hơn là tránh nó ở những khu vực quan trọng. Kiểm tra lengthtrong trường hợp này là điều tốt nhất bạn có thể làm, vì giá trị indexsẽ luôn ít hơn thì cái lengthindexsẽ được dịch chuyển và trở thành cái mới indexnếu bạn là removechúng, vì vậy đó là lý do tại sao quy tắc kiểm tra lengthluôn hoạt động.
SSpoke

1
@SSpoke ... Trong khi tôi đồng ý, thử / bắt không phải là câu trả lời 'tốt'; nó sẽ giải quyết vấn đề khi danh sách thưa thớt. Tôi thích đề xuất sử dụng một mảng: Object [] ary; dưới đây hoặc một băm.
sẽ

12

Đây là những gì bạn cần ...

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

Tại sao không sử dụng một mảng cũ đơn giản? Tôi nghĩ rằng quyền truy cập được lập chỉ mục vào một Danh sách là một mùi mã.


3
Không phải lúc nào cũng vậy, vì anh ấy có thể muốn ArrayList phát triển theo thời gian và điều đó một mảng không thể làm được.
Coyote21

7

Thường thì tôi chỉ kiểm tra xem chỉ số có nhỏ hơn kích thước mảng hay không

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

Nếu bạn cũng lo lắng về việc chỉ mục là một giá trị âm, hãy sử dụng

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

1
Làm thế nào điều này cung cấp bất kỳ giá trị nào so với Câu trả lời đã được chấp nhận của vài năm trước?
Basil Bourque

2
Tôi đoán theo quan điểm của bạn, nó không cung cấp bất kỳ giá trị nào, nhưng tôi đã thấy một bình luận của roberto tomás về câu trả lời được chấp nhận, giả sử rằng anh ta không hoàn toàn hiểu câu trả lời được chấp nhận. hãy kiểm tra "với một danh sách mới, tôi sẽ bắt đầu ở index = 0 và list.size () == 0 của tôi nữa. Vì vậy, lần đầu tiên tôi kiểm tra nó sẽ đúng" Tôi quyết định đăng một câu trả lời riêng để trợ giúp bất kỳ sự nhầm lẫn nào trong tương lai.
AamirR

6

Về bản cập nhật của bạn (có thể là một câu hỏi khác). Bạn nên sử dụng một mảng các đối tượng này thay vì ArrayList, vì vậy bạn có thể chỉ cần kiểm tra giá trị cho null:

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

Thực hành tốt nhất

Nếu bạn không có hàng trăm mục nhập trong mảng của mình, bạn nên xem xét tổ chức nó như một lớp để loại bỏ các số kỳ diệu 3,8, v.v.

Kiểm soát luồng sử dụng ngoại lệ là một phương pháp không tốt.


1
Nếu mảng [8] không tồn tại, bạn sẽ gặp ArrayIndexOutOfBoundException.
Nitesh Kumar Anand


3

Bạn có thể kiểm tra kích thước của một ArrayListbằng size()phương pháp này. Điều này sẽ trả về chỉ số tối đa +1


2

một cách đơn giản để làm điều này:

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

1

Kiểm tra nhanh và bẩn để biết chỉ mục có tồn tại hay không. trong danh sách thay thế triển khai của bạn Với danh sách của bạn, bạn đang thử nghiệm.

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

hoặc cho 2Dimensional ArrayLists ...

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

1
Danh sách không có .lengthnó có list.size()nhưng không có gì to tát, tôi luôn gặp rắc rối như thế này haha ​​Tôi dựa vào trình biên dịch để hướng dẫn tôi về cái đó. Có thể bạn đang nghĩ đến việc mảng nguyên thủy
SSpoke

1
Cảm ơn vì đã nắm bắt được điều đó. Cardinality của hộp đựng có thể dễ dàng bị quên.
t3dodson

0

Nếu chỉ mục của bạn nhỏ hơn kích thước của danh sách thì nó vẫn tồn tại, có thể có nullgiá trị. Nếu chỉ mục lớn hơn thì bạn có thể gọi ensureCapacity() để có thể sử dụng chỉ mục đó.

Nếu bạn muốn kiểm tra xem giá trị trong chỉ mục của bạn có nullhay không, hãy gọiget()


1
Việc gọi ensureCapacity (int) sẽ không làm tăng kích thước của Danh sách mà chỉ tăng dung lượng; tức là "kích thước tiềm năng" để tra cứu chỉ mục ngoài giới hạn vẫn không thành công.
Adamski

Ngoài ra, tại sao lại gọi ensureCapacity (int)? Đó có thể là một hoạt động cực kỳ tốn kém nếu ví dụ như kích thước hiện tại của danh sách là 5 và bạn muốn xác định giá trị của mục #: 100.000.000.
Adamski

Ý tôi là các chỉ số nhỏ hơn size () luôn tồn tại, những chỉ số> = size () thì không và không thể sử dụng chúng (== gọi set ()) cho đến khi danh sách trở nên đủ lớn. Thực sự gọi ensureCapacity là không đủ, người ta cần thay đổi kích thước bằng cách thêm các phần tử.
Dmitry

Giải thích sai về những gì đảm bảoCapacity (int) thực sự làm. Nó không có tác dụng gì với kích thước ArrayList.
Mohsen

0

Bạn có thể kiểm tra kích thước của mảng.

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'
    }
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.