Làm cách nào để xác định xem một mảng có chứa một giá trị cụ thể trong Java không?


2277

Tôi có một String[]giá trị như vậy:

public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};

Cho String s, có một cách tốt để kiểm tra xem VALUEScó chứa s?


5
Đi đường dài, nhưng bạn có thể sử dụng vòng lặp for: "for (Chuỗi s: VALUES) if (s.equals (" MYVALUE ")) trả về đúng;
Zack

70
@camickr. Đối với câu hỏi của bạn, tôi nêu lên câu hỏi này và câu trả lời của bạn -now- bởi vì nó đã tiết kiệm cho tôi 30 phút và 20 dòng mã viết xấu cho các vòng lặp, -now-. Không đọc nó ba năm trước. (BTW, cảm ơn :))
Theo đuổi

3
@ camickr - Tôi có một tình huống gần như giống hệt với tình huống này: stackoverflow.com/a/223929/12943 Nó chỉ tiếp tục nhận được phiếu bầu mà chỉ là một bản sao / dán từ tài liệu của mặt trời. Tôi đoán điểm số được dựa trên số lượng trợ giúp của bạn và không phải bạn đã bỏ ra bao nhiêu nỗ lực - và chủ yếu là bạn đăng nó nhanh như thế nào! Có lẽ chúng ta đã vấp phải bí mật của John Skeet! Vâng câu trả lời tốt, +1 cho bạn.
Bill K

1
Nếu bạn đang sử dụng Apache Commons, thì org.apache.commons.lang.ArrayUtils.contains () thực hiện điều này cho bạn.
Cậu bé

34
@camickr vì mọi người, như tôi, google một câu hỏi, nhấp vào kết quả SO, xem câu trả lời của bạn, kiểm tra nó, nó hoạt động, đưa ra câu trả lời và sau đó rời đi.
Aequitas

Câu trả lời:


2924
Arrays.asList(yourArray).contains(yourValue)

Cảnh báo: điều này không hoạt động đối với các mảng nguyên thủy (xem các bình luận).


Từ bây giờ bạn có thể sử dụng Luồng.

String[] values = {"AB","BC","CD","AE"};
boolean contains = Arrays.stream(values).anyMatch("s"::equals);

Để kiểm tra xem một mảng của int, doublehoặc longchứa một giá trị sử dụng IntStream, DoubleStreamhoặc LongStreamtương ứng.

Thí dụ

int[] a = {1,2,3,4};
boolean contains = IntStream.of(a).anyMatch(x -> x == 4);

87
Tôi hơi tò mò về hiệu năng của điều này so với các hàm tìm kiếm trong lớp Mảng so với lặp lại trên một mảng và sử dụng hàm equals () hoặc == cho các nguyên hàm.
Thomas Owens

186
Bạn không mất nhiều, vì asList () trả về một ArrayList có một mảng ở giữa. Hàm tạo sẽ chỉ thay đổi một tham chiếu để không có nhiều việc phải làm ở đó. Và chứa () / indexOf () sẽ lặp lại và sử dụng bằng (). Đối với người nguyên thủy, bạn nên tốt hơn là tự mình viết mã. Đối với Chuỗi hoặc các lớp khác, sự khác biệt sẽ không được chú ý.
Joey

18
Lạ lùng, NetBeans tuyên bố rằng 'Arrays.asList (ngày lễ)' cho một 'int [] holiday' trả về một 'danh sách <int []>' chứ không phải 'danh sách <int>'. Nó chỉ chứa một yếu tố duy nhất. Có nghĩa là Chứa không hoạt động vì nó chỉ có một yếu tố; mảng int.
Nyerguds

62
Nyerguds: thực sự, điều này không hoạt động cho người nguyên thủy. Trong các kiểu nguyên thủy java không thể chung chung. asList được khai báo là <T> List <T> asList (T ...). Khi bạn chuyển một int [] vào nó, trình biên dịch sẽ nhập T = int [] vì nó không thể suy ra T = int, bởi vì các nguyên hàm không thể là chung.
CromTheDestroyer

28
@Joey chỉ là một ghi chú bên lề, đó là một ArrayList, nhưng không java.util.ArrayListnhư bạn mong đợi, lớp thực được trả về là: java.util.Arrays.ArrayList<E>được định nghĩa là : public class java.util.Arrays {private static class ArrayList<E> ... {}}.
TWiStErRob

362

Cập nhật ngắn gọn cho Java SE 9

Mảng tham chiếu là xấu. Đối với trường hợp này, chúng tôi là sau một bộ. Kể từ Java SE 9 chúng ta có Set.of.

private static final Set<String> VALUES = Set.of(
    "AB","BC","CD","AE"
);

"Đã cho Chuỗi s, có cách nào tốt để kiểm tra xem GIÁ TRỊ có chứa s không?"

VALUES.contains(s)

O (1).

Các loại đúng , bất biến , O (1)súc tích . Xinh đẹp.*

Chi tiết câu trả lời gốc

Chỉ cần xóa mã để bắt đầu. Chúng tôi đã (sửa):

public static final String[] VALUES = new String[] {"AB","BC","CD","AE"};

Đây là một tĩnh có thể thay đổi mà FindBugs sẽ nói với bạn là rất nghịch ngợm. Không sửa đổi số liệu thống kê và không cho phép các mã khác cũng làm như vậy. Ở mức tối thiểu, trường phải ở chế độ riêng tư:

private static final String[] VALUES = new String[] {"AB","BC","CD","AE"};

(Lưu ý, bạn thực sự có thể thả new String[];bit.)

Mảng tham chiếu vẫn còn xấu và chúng tôi muốn có một bộ:

private static final Set<String> VALUES = new HashSet<String>(Arrays.asList(
     new String[] {"AB","BC","CD","AE"}
));

(Những người hoang tưởng, như bản thân tôi, có thể cảm thấy thoải mái hơn nếu điều này được gói gọn Collections.unmodifiableSet- thậm chí nó có thể được công khai.)

(* Để nói thêm một chút về thương hiệu, API bộ sưu tập có thể dự đoán vẫn còn thiếu các loại bộ sưu tập bất biến và cú pháp vẫn còn quá dài dòng, theo sở thích của tôi.)


184
Ngoại trừ O (N) để tạo bộ sưu tập ở vị trí đầu tiên :)
Drew Noakes

61
Nếu nó tĩnh, có lẽ nó sẽ được sử dụng khá nhiều lần. Vì vậy, thời gian để khởi tạo tập hợp có cơ hội khá nhỏ so với chi phí của rất nhiều tìm kiếm tuyến tính.
Xr.

1
Tạo sau đó bộ sưu tập sẽ bị chi phối bởi thời gian tải mã (về mặt kỹ thuật là O (n) nhưng thực tế không đổi).
Tom Hawtin - tackline

2
@ TomHawtin-tackline Tại sao bạn nói "đặc biệt ở đây chúng tôi muốn có một bộ"? Lợi thế của một bộ (Hashset) trong trường hợp này là gì? Tại sao "mảng tham chiếu" xấu (bởi "mảng tham chiếu", ý bạn là một ArrayList được hỗ trợ bởi một mảng như được tạo bởi một lệnh gọi Arrays.asList)?
Basil Bourque

6
@nmr A TreeSetsẽ là O(log n). HashSets được chia tỷ lệ sao cho số phần tử trung bình trong một thùng gần như không đổi. Ít nhất là cho các mảng lên tới 2 ^ 30. Có thể có những ảnh hưởng từ các bộ nhớ cache phần cứng mà phân tích big-O bỏ qua. Cũng giả sử chức năng băm đang hoạt động hiệu quả.
Tom Hawtin - tackline

206

Bạn có thể sử dụng ArrayUtils.containstừ Apache Commons Lang

public static boolean contains(Object[] array, Object objectToFind)

Lưu ý rằng phương thức này trả về falsenếu mảng đã qua là null.

Ngoài ra còn có các phương thức có sẵn cho các mảng nguyên thủy của tất cả các loại.

Thí dụ:

String[] fieldsToInclude = { "id", "name", "location" };

if ( ArrayUtils.contains( fieldsToInclude, "id" ) ) {
    // Do some stuff.
}

4
@ max4ever Tôi đồng ý, nhưng điều này vẫn tốt hơn sau đó "tự lăn" và dễ đọc hơn theo cách java thô.
Jason


38
@ max4ever Đôi khi bạn đã có thư viện này (vì những lý do khác) và đó là một câu trả lời hoàn toàn hợp lệ. Tôi đã tìm kiếm cái này và tôi đã phụ thuộc vào Apache Commons Lang. Cảm ơn câu trả lời này.
GuiSim

1
Hoặc bạn chỉ có thể sao chép phương thức (và tùy thuộc nếu có).
Trâu

10
@ max4ever Hầu hết các ứng dụng Android được Proguard tối thiểu hóa, chỉ đưa các lớp và chức năng bạn cần vào ứng dụng của mình. Điều đó làm cho nó bằng cách cuộn của riêng bạn, hoặc sao chép nguồn của điều apache. Và bất cứ ai không sử dụng tối thiểu hóa đó đều không cần phải phàn nàn về 700kb hoặc 78kb :)
Kenyakorn Ketsombut

158

Chỉ cần thực hiện nó bằng tay:

public static <T> boolean contains(final T[] array, final T v) {
    for (final T e : array)
        if (e == v || v != null && v.equals(e))
            return true;

    return false;
}

Cải thiện:

Điều v != nullkiện là không đổi bên trong phương thức. Nó luôn ước tính cùng giá trị Boolean trong khi gọi phương thức. Vì vậy, nếu đầu vào arraylớn, sẽ hiệu quả hơn khi chỉ đánh giá điều kiện này một lần và chúng ta có thể sử dụng điều kiện đơn giản hóa / nhanh hơn bên trong forvòng lặp dựa trên kết quả. contains()Phương pháp cải tiến :

public static <T> boolean contains2(final T[] array, final T v) {
    if (v == null) {
        for (final T e : array)
            if (e == null)
                return true;
    } 
    else {
        for (final T e : array)
            if (e == v || v.equals(e))
                return true;
    }

    return false;
}

9
@Phoexo Giải pháp này rõ ràng là nhanh hơn vì câu trả lời được chấp nhận bao bọc mảng thành một danh sách và gọi phương thức chứa () trong danh sách đó trong khi giải pháp của tôi về cơ bản chỉ làm những gì chứa ().
icza

10
@AlastorMoody e == v thực hiện kiểm tra đẳng thức tham chiếu rất nhanh. Nếu cùng một đối tượng (cùng tham chiếu) nằm trong mảng, nó sẽ được tìm thấy nhanh hơn. Nếu nó không phải là cùng một thể hiện, nó vẫn có thể giống như được yêu cầu bởi phương thức equals (), đây là những gì được kiểm tra nếu các tham chiếu không giống nhau.
icza

20
Tại sao chức năng này không phải là một phần của Java? Không có gì ngạc nhiên khi mọi người nói Java đang cồng kềnh ... hãy xem tất cả các câu trả lời ở trên này sử dụng một loạt các thư viện khi tất cả những gì bạn cần là một vòng lặp for. Bọn nhóc thời nay!
phreakhead

4
@phreakhead Đây là một phần của Java, xemCollection.contains(Object)
Steve Kuo

11
@icza Nếu bạn nhìn vào nguồn của ArraysArrayListhóa ra điều này không nhất thiết phải nhanh hơn phiên bản sử dụng Arrays.asList(...).contains(...). Chi phí tạo ra một ArrayListcực kỳ nhỏ và ArrayList.contains()sử dụng một vòng lặp thông minh hơn (thực tế nó sử dụng hai vòng lặp khác nhau) so với vòng lặp được hiển thị ở trên (JDK 7).
Axel

72

Bốn cách khác nhau để kiểm tra nếu một mảng chứa giá trị

1) Danh sách sử dụng:

public static boolean useList(String[] arr, String targetValue) {
    return Arrays.asList(arr).contains(targetValue);
}

2) Sử dụng Set:

public static boolean useSet(String[] arr, String targetValue) {
    Set<String> set = new HashSet<String>(Arrays.asList(arr));
    return set.contains(targetValue);
}

3) Sử dụng một vòng lặp đơn giản:

public static boolean useLoop(String[] arr, String targetValue) {
    for (String s: arr) {
        if (s.equals(targetValue))
            return true;
    }
    return false;
}

4) Sử dụng Arrays.binarySearch ():

Mã dưới đây là sai, nó được liệt kê ở đây cho đầy đủ. binarySearch () CHỈ có thể được sử dụng trên các mảng được sắp xếp. Bạn sẽ tìm thấy kết quả là kỳ lạ dưới đây. Đây là tùy chọn tốt nhất khi mảng được sắp xếp.

public static boolean binarySearch(String[] arr, String targetValue) {  
            int a = Arrays.binarySearch(arr, targetValue);
            return a > 0;
        }

Ví dụ nhanh:

String testValue="test";
String newValueNotInList="newValue";
String[] valueArray = { "this", "is", "java" , "test" };
Arrays.asList(valueArray).contains(testValue); // returns true
Arrays.asList(valueArray).contains(newValueNotInList); // returns false

5
ví dụ tìm kiếm nhị phân của bạn sẽ trả về a> 0;
Will Sherwood

6
Tại sao? Tôi nghĩ rằng nó sẽ trả về a> -1, vì 0 sẽ chỉ ra rằng nó được chứa ở phần đầu của mảng.
meyow

1
Biến thể đầu tiên với (a >= 0)là chính xác, chỉ cần kiểm tra các tài liệu , họ nói "Lưu ý rằng điều này đảm bảo rằng giá trị trả về sẽ> = 0 khi và chỉ khi tìm thấy khóa".
Yoory N.

Tại sao hoạt động với String mà không phải int? boolean tĩnh tồn tại (int [] ints, int k) {return Arrays.asList (ints) .contains (k); }
Willians Martins

71

Nếu mảng không được sắp xếp, bạn sẽ phải lặp đi lặp lại mọi thứ và thực hiện cuộc gọi bằng nhau trên mỗi mảng.

Nếu mảng được sắp xếp, bạn có thể thực hiện tìm kiếm nhị phân, có một mảng trong lớp Mảng .

Nói chung, nếu bạn định thực hiện nhiều kiểm tra thành viên, bạn có thể muốn lưu trữ mọi thứ trong Tập hợp, không phải trong một mảng.


1
Ngoài ra, như tôi đã nói trong câu trả lời của mình, nếu bạn sử dụng lớp Arrays, bạn có thể sắp xếp mảng sau đó thực hiện tìm kiếm nhị phân trên mảng vừa được sắp xếp.
Thomas Owens

1
@Thomas: Tôi đồng ý. Hoặc bạn chỉ có thể thêm mọi thứ vào một TreeSet; cùng độ phức tạp. Tôi sẽ sử dụng Mảng nếu nó không thay đổi (có thể tiết kiệm một chút địa phương bộ nhớ vì các tham chiếu được đặt liền kề mặc dù các chuỗi không). Tôi sẽ sử dụng bộ nếu điều này sẽ thay đổi theo thời gian.
Uri

49

Để biết giá trị của nó, tôi đã chạy thử nghiệm so sánh 3 gợi ý về tốc độ. Tôi đã tạo các số nguyên ngẫu nhiên, chuyển đổi chúng thành Chuỗi và thêm chúng vào một mảng. Sau đó tôi đã tìm kiếm số / chuỗi cao nhất có thể, đó sẽ là trường hợp xấu nhất choasList().contains() .

Khi sử dụng kích thước mảng 10K, kết quả là:

Sắp xếp và tìm kiếm: 15
Tìm kiếm nhị phân: 0
asList.contains: 0

Khi sử dụng mảng 100K, kết quả là:

Sắp xếp và tìm kiếm: 156
Tìm kiếm nhị phân: 0
asList.contains: 32

Vì vậy, nếu mảng được tạo theo thứ tự sắp xếp, tìm kiếm nhị phân là nhanh nhất, nếu không thì asList().containsđó sẽ là cách để đi. Nếu bạn có nhiều tìm kiếm, thì có thể đáng để sắp xếp mảng để bạn có thể sử dụng tìm kiếm nhị phân. Tất cả phụ thuộc vào ứng dụng của bạn.

Tôi nghĩ đó là những kết quả mà hầu hết mọi người mong đợi. Đây là mã kiểm tra:

import java.util.*;

public class Test
{
    public static void main(String args[])
    {
        long start = 0;
        int size = 100000;
        String[] strings = new String[size];
        Random random = new Random();


        for (int i = 0; i < size; i++)
            strings[i] = "" + random.nextInt( size );

        start = System.currentTimeMillis();
        Arrays.sort(strings);
        System.out.println(Arrays.binarySearch(strings, "" + (size - 1) ));
        System.out.println("Sort & Search : " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        System.out.println(Arrays.binarySearch(strings, "" + (size - 1) ));
        System.out.println("Search        : " + (System.currentTimeMillis() - start));

        start = System.currentTimeMillis();
        System.out.println(Arrays.asList(strings).contains( "" + (size - 1) ));
        System.out.println("Contains      : " + (System.currentTimeMillis() - start));
    }
}

6
Tôi không hiểu mã này. Bạn sắp xếp mảng 'chuỗi' và sử dụng cùng một mảng (được sắp xếp) trong cả hai lệnh gọi tới binarySearch. Làm thế nào điều đó có thể hiển thị bất cứ điều gì ngoại trừ tối ưu hóa thời gian chạy HotSpot? Tương tự với lệnh gọi asList.contains. Bạn tạo một danh sách từ mảng được sắp xếp và sau đó chứa trên đó với giá trị cao nhất. Tất nhiên là nó sẽ mất thời gian. Ý nghĩa của bài kiểm tra này là gì? Không đề cập đến việc là một microbenchmark được viết không đúng cách
Erik

Ngoài ra, vì tìm kiếm nhị phân chỉ có thể được áp dụng cho một tập hợp được sắp xếp, sắp xếp và tìm kiếm là cách khả thi duy nhất để sử dụng tìm kiếm nhị phân.
Erik

Sắp xếp có thể đã được thực hiện vì một số lý do khác, ví dụ, nó có thể được sắp xếp trên init và không bao giờ thay đổi. Có sử dụng trong thời gian tìm kiếm thử nghiệm của riêng mình. Tuy nhiên, trường hợp này rơi xuống là một ví dụ ít xuất sắc hơn của microbenchmarking. Microbenchmark nổi tiếng là khó khăn để có được ngay trong Java và ví dụ, bao gồm thực thi mã kiểm tra đủ để có được tối ưu hóa điểm nóng trước khi chạy thử nghiệm thực tế, chứ đừng nói đến việc chạy mã kiểm tra thực tế hơn ONCE với bộ hẹn giờ.
Cạm

7
Thử nghiệm này còn thiếu sót vì nó chạy cả 3 thử nghiệm trong cùng một cá thể JVM. Các thử nghiệm sau này có thể được hưởng lợi từ các thử nghiệm trước đó làm nóng bộ đệm, JIT, v.v.
Steve Kuo

4
Thử nghiệm này thực sự hoàn toàn không liên quan. Sắp xếp & Tìm kiếm là độ phức tạp tuyến tính (n * log (n)), tìm kiếm nhị phân là logarit và ArrayUtils.contains rõ ràng là tuyến tính. Không có ích để so sánh các giải pháp này vì chúng thuộc các lớp phức tạp hoàn toàn khác nhau.
kéo

37

Thay vì sử dụng cú pháp khởi tạo mảng nhanh quá, bạn chỉ có thể khởi tạo nó dưới dạng Danh sách theo cách tương tự bằng cách sử dụng phương thức Arrays.asList, ví dụ:

public static final List<String> STRINGS = Arrays.asList("firstString", "secondString" ...., "lastString");

Sau đó, bạn có thể làm (như trên):

STRINGS.contains("the string you want to find");

35

Với Java 8, bạn có thể tạo một luồng và kiểm tra xem có bất kỳ mục nào trong luồng phù hợp không "s":

String[] values = {"AB","BC","CD","AE"};
boolean sInArray = Arrays.stream(values).anyMatch("s"::equals);

Hoặc như một phương pháp chung:

public static <T> boolean arrayContains(T[] array, T value) {
    return Arrays.stream(array).anyMatch(value::equals);
}

3
Cũng đáng lưu ý các chuyên ngành nguyên thủy.
skiwi

Ngoài ra, anyMatchJavaDoc cũng nói rằng "...May not evaluate the predicate on all elements if not necessary for determining the result."nó có thể không cần tiếp tục xử lý sau khi tìm thấy kết quả khớp.
mkobit

28

Bạn có thể sử dụng lớp Mảng để thực hiện tìm kiếm nhị phân cho giá trị. Nếu mảng của bạn không được sắp xếp, bạn sẽ phải sử dụng các hàm sắp xếp trong cùng một lớp để sắp xếp mảng, sau đó tìm kiếm qua nó.


Bạn có thể sử dụng các hàm sắp xếp trong cùng một lớp để thực hiện điều đó ... Tôi nên thêm nó vào câu trả lời của mình.
Thomas Owens

1
Có lẽ sẽ có giá cao hơn cách tiếp cận asList (). Chứa (), sau đó, tôi nghĩ vậy. Trừ khi bạn cần thực hiện kiểm tra đó thường xuyên (nhưng nếu đó chỉ là một danh sách tĩnh các giá trị có thể được sắp xếp để bắt đầu, thì công bằng).
Joey

Thật. Có rất nhiều biến số sẽ là hiệu quả nhất. Thật tốt khi có các lựa chọn mặc dù.
Thomas Owens

Một số mã thực hiện điều này tại đây: stackoverflow.com/a/48242328/9131078
OOBalance

Sắp xếp toàn bộ một mảng cho mục đích tìm kiếm là tốn kém. Chúng ta có thể sử dụng cùng thời gian CPU cho chính tìm kiếm lót. Tôi thích tìm kiếm nhị phân trên một bộ sưu tập đã được xây dựng theo thứ tự sắp xếp trước.
arunwithasmile

17

ObStoolAnswer (nhưng tôi nghĩ có một bài học ở đây ở đâu đó):

enum Values {
    AB, BC, CD, AE
}

try {
    Values.valueOf(s);
    return true;
} catch (IllegalArgumentException exc) {
    return false;
}

1
Ném ngoại lệ rõ ràng là nặng nhưng đây sẽ là một cách mới để kiểm tra giá trị nếu nó hoạt động. Nhược điểm là enum phải được xác định trước.
James P.

13

Trên thực tế, nếu bạn sử dụng Hashset <String> như Tom Hawtin đề xuất, bạn không cần phải lo lắng về việc sắp xếp và tốc độ của bạn cũng giống như với tìm kiếm nhị phân trên một mảng được định sẵn, thậm chí có thể nhanh hơn.

Tất cả phụ thuộc vào cách mã của bạn được thiết lập, rõ ràng, nhưng từ nơi tôi đứng, thứ tự sẽ là:

Trên một mảng chưa được sắp xếp :

  1. Hashset
  2. asList
  3. sắp xếp & nhị phân

Trên một mảng được sắp xếp:

  1. Hashset
  2. Nhị phân
  3. asList

Vì vậy, một trong hai cách, Hashset cho chiến thắng.


2
Tư cách thành viên Hashset phải là O (1) và tìm kiếm nhị phân trên bộ sưu tập được sắp xếp là O (log n).
Skylar Saveland

11

Nếu bạn có thư viện bộ sưu tập google, câu trả lời của Tom có ​​thể được đơn giản hóa rất nhiều bằng cách sử dụng Immutable Set (http://google-collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Immutableset.html)

Điều này thực sự loại bỏ rất nhiều lộn xộn từ khởi tạo được đề xuất

private static final Set<String> VALUES =  ImmutableSet.of("AB","BC","CD","AE");

10

Một giải pháp khả thi:

import java.util.Arrays;
import java.util.List;

public class ArrayContainsElement {
  public static final List<String> VALUES = Arrays.asList("AB", "BC", "CD", "AE");

  public static void main(String args[]) {

      if (VALUES.contains("AB")) {
          System.out.println("Contains");
      } else {
          System.out.println("Not contains");
      }
  }
}

8

Các nhà phát triển thường làm:

Set<String> set = new HashSet<String>(Arrays.asList(arr));
return set.contains(targetValue);

Đoạn mã trên hoạt động, nhưng không cần phải chuyển đổi danh sách để đặt đầu tiên. Chuyển đổi một danh sách thành một bộ đòi hỏi thêm thời gian. Nó có thể đơn giản như:

Arrays.asList(arr).contains(targetValue);

hoặc là

   for(String s: arr){
        if(s.equals(targetValue))
            return true;
    }

return false;

Cái đầu tiên dễ đọc hơn cái thứ hai.


7

Sử dụng một vòng lặp đơn giản là cách hiệu quả nhất để làm điều này.

boolean useLoop(String[] arr, String targetValue) {
    for(String s: arr){
        if(s.equals(targetValue))
            return true;
    }
    return false;
}

Courtesy để Programcreek


Điều này sẽ đưa ra một ngoại lệ con trỏ null nếu mảng chứa tham chiếu null trước giá trị đích.
Phường Samuel Edwin

1
câu lệnh if nên là: if (targetValue.equals (s)) vì String bằng có trình kiểm tra thể hiện.
TheArchon

sử dụng Object.equals (obj1, obj2) thay vào đó là null an toàn.
bộ ba

7

Trong Java 8 sử dụng Luồng.

List<String> myList =
Arrays.asList("a1", "a2", "b1", "c2", "c1");

myList
.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);

7
Có bất kỳ lợi thế với phương pháp này?
Julian Stadler

1
Nó không trả lời câu hỏi.
Florian F

5
  1. Đối với các mảng có độ dài giới hạn, sử dụng như sau (như được đưa ra bởi camickr ). Điều này chậm đối với các kiểm tra lặp đi lặp lại, đặc biệt đối với các mảng dài hơn (tìm kiếm tuyến tính).

     Arrays.asList(...).contains(...)
  2. Để có hiệu suất nhanh nếu bạn liên tục kiểm tra một bộ phần tử lớn hơn

    • Một mảng là cấu trúc sai. Sử dụng a TreeSetvà thêm từng yếu tố cho nó. Nó sắp xếp các phần tử và có một exist()phương thức nhanh (tìm kiếm nhị phân).

    • Nếu các yếu tố thực hiện Comparable& bạn muốn TreeSetsắp xếp phù hợp:

      ElementClass.compareTo()Phương pháp phải tương thích với ElementClass.equals(): xem Triads không hiển thị để chiến đấu? (Java Set thiếu một mục)

      TreeSet myElements = new TreeSet();
      
      // Do this for each element (implementing *Comparable*)
      myElements.add(nextElement);
      
      // *Alternatively*, if an array is forceably provided from other code:
      myElements.addAll(Arrays.asList(myArray));
    • Nếu không, sử dụng của riêng bạn Comparator:

      class MyComparator implements Comparator<ElementClass> {
           int compareTo(ElementClass element1; ElementClass element2) {
                // Your comparison of elements
                // Should be consistent with object equality
           }
      
           boolean equals(Object otherComparator) {
                // Your equality of comparators
           }
      }
      
      
      // construct TreeSet with the comparator
      TreeSet myElements = new TreeSet(new MyComparator());
      
      // Do this for each element (implementing *Comparable*)
      myElements.add(nextElement);
    • Phần thưởng: kiểm tra sự tồn tại của một số phần tử:

      // Fast binary search through sorted elements (performance ~ log(size)):
      boolean containsElement = myElements.exists(someElement);

4
Tại sao phải bận tâm với TreeSet? HashSetnhanh hơn (O (1)) và không yêu cầu đặt hàng.
Sean Owen

4

Thử cái này:

ArrayList<Integer> arrlist = new ArrayList<Integer>(8);

// use add() method to add elements in the list
arrlist.add(20);
arrlist.add(25);
arrlist.add(10);
arrlist.add(15);

boolean retval = arrlist.contains(10);
if (retval == true) {
    System.out.println("10 is contained in the list");
}
else {
    System.out.println("10 is not contained in the list");
}

4

Sử dụng như sau ( contains()phương thức ArrayUtils.in()trong mã này):

ObjectUtils.java

public class ObjectUtils{

    /**
     * A null safe method to detect if two objects are equal.
     * @param object1
     * @param object2
     * @return true if either both objects are null, or equal, else returns false.
     */
    public static boolean equals(Object object1, Object object2){
        return object1==null ? object2==null : object1.equals(object2);
    }

}

ArrayUtils.java

public class ArrayUtils{

    /**
     * Find the index of of an object is in given array, starting from given inclusive index.
     * @param ts  Array to be searched in.
     * @param t  Object to be searched.
     * @param start  The index from where the search must start.
     * @return Index of the given object in the array if it is there, else -1.
     */
    public static <T> int indexOf(final T[] ts, final T t, int start){
        for(int i = start; i < ts.length; ++i)
            if(ObjectUtils.equals(ts[i], t))
                return i;
        return -1;
    }

    /**
     * Find the index of of an object is in given array, starting from 0;
     * @param ts  Array to be searched in.
     * @param t  Object to be searched.
     * @return  indexOf(ts, t, 0)
     */
    public static <T> int indexOf(final T[] ts, final T t){
        return indexOf(ts, t, 0);
    }

    /**
     * Detect if the given object is in the given array.
     * @param ts  Array to be searched in.
     * @param t  Object to be searched.
     * @return  If indexOf(ts, t) is greater than -1.
     */
    public static <T> boolean in(final T[] ts, final T t){
        return indexOf(ts, t) > -1 ;
    }

}

Như bạn có thể thấy trong đoạn mã trên, có những phương thức tiện ích khác ObjectUtils.equals()ArrayUtils.indexOf()cũng được sử dụng ở những nơi khác.


Tôi rất muộn để tham gia cuộc thảo luận này, nhưng vì cách tiếp cận của tôi trong việc giải quyết vấn đề này, khi tôi đối mặt với nó vài năm trước, có một chút khác biệt so với các câu trả lời khác đã được đăng ở đây, tôi đang đăng giải pháp mà tôi đã sử dụng vào thời điểm đó, ở đây, trong trường hợp bất cứ ai thấy nó hữu ích.
Abhishek Oza

3

Kiểm tra điều này

String[] VALUES = new String[] {"AB","BC","CD","AE"};
String s;

for(int i=0; i< VALUES.length ; i++)
{
    if ( VALUES[i].equals(s) )
    { 
        // do your stuff
    } 
    else{    
        //do your stuff
    }
}

1
Điều này không hoạt động - nó sẽ nhập elsecho mọi mục không khớp (vì vậy nếu bạn đang tìm kiếm "AB" trong mảng đó, nó sẽ đến đó 3 lần, vì 3 trong số các giá trị không phải là "AB ").
Bernhard Barker

3

Arrays.asList () -> sau đó gọi phương thức chứa () sẽ luôn hoạt động, nhưng thuật toán tìm kiếm sẽ tốt hơn nhiều vì bạn không cần phải tạo một trình bao bọc danh sách nhẹ xung quanh mảng, đó là những gì Arrays.asList () làm .

public boolean findString(String[] strings, String desired){
   for (String str : strings){
       if (desired.equals(str)) {
           return true;
       }
   }
   return false; //if we get here… there is no desired String, return false.
}

Arrays.asListkhông phải là O (n). Nó chỉ là một cái bọc nhẹ. Có một cái nhìn vào việc thực hiện.
Patrick Parker

3

Nếu bạn không muốn nó là trường hợp nhạy cảm

Arrays.stream(VALUES).anyMatch(s::equalsIgnoreCase);

2

Sử dụng Array.BinarySearch(array,obj) để tìm đối tượng đã cho trong mảng hay không.

Thí dụ:

if (Array.BinarySearch(str, i) > -1)`  true --exists

sai - không tồn tại


4
Array.BinarySearchArray.FindIndexlà các phương thức .NET và không tồn tại trong Java.
ataylor

@ataylor có Arrays.binarySearch trong java. Nhưng bạn đã đúng, không có Arrays.find Index
mente

Cần lưu ý:The array must be sorted prior to making this call. If it is not sorted, the results are undefined.
Dorian Gray

1

Tạo một boolean ban đầu được đặt thành false. Chạy một vòng lặp để kiểm tra mọi giá trị trong mảng và so sánh với giá trị bạn đang kiểm tra. Nếu bạn nhận được một trận đấu, đặt boolean thành true và dừng vòng lặp. Sau đó khẳng định rằng boolean là đúng.


1

Thử sử dụng phương thức kiểm tra vị ngữ Java 8

Dưới đây là một ví dụ đầy đủ về nó.

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
public class Test {
 public static final List<String> VALUES = Arrays.asList("AA", "AB", "BC", "CD", "AE");

 public static void main(String args[]) {
  Predicate<String> containsLetterA = VALUES -> VALUES.contains("AB");
  for (String i : VALUES) {

   System.out.println(containsLetterA.test(i));
  } 
 }
}

http://mytĩ Dù

https://github.com/VipulGulhane1/java8/blob/master/Test.java


0

việc sử dụng Spliterator ngăn chặn việc tạo ra một List

boolean found = false;  // class variable

String search = "AB";
Spliterator<String> spl = Arrays.spliterator( VALUES, 0, VALUES.length );
while( (! found) && spl.tryAdvance(o -> found = o.equals( search )) );

found == truenếu searchđược chứa trong mảng


điều này không làm việc cho các mảng nguyên thủy

public static final int[] VALUES = new int[] {1, 2, 3, 4};
boolean found = false;  // class variable

int search = 2;
Spliterator<Integer> spl = Arrays.spliterator( VALUES, 0, VALUES.length );


-2

Bạn có thể kiểm tra nó bằng hai phương pháp

A) Bằng cách chuyển đổi mảng thành chuỗi và sau đó kiểm tra chuỗi yêu cầu bằng phương thức .contains

 String a=Arrays.toString(VALUES);
    System.out.println(a.contains("AB"));
    System.out.println(a.contains("BC"));
    System.out.println(a.contains("CD"));
    System.out.println(a.contains("AE"));

B) đây là một phương pháp hiệu quả hơn

 Scanner s=new Scanner(System.in);


   String u=s.next();
   boolean d=true;
    for(int i=0;i<VAL.length;i++)
    {
        if(VAL[i].equals(u)==d)
            System.out.println(VAL[i] +" "+u+VAL[i].equals(u));  

    }

1
Chuyển đổi chuỗi không hiệu quả một cách vô lý và giải pháp không chính xác, ví dụ: chứa (",") sẽ trả về đúng.
Atuos
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.