[java] 배열에 Java의 특정 값이 포함되어 있는지 어떻게 확인합니까?

나는 다음 String[]과 같은 값을 가지고있다 :

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

을 감안할 때 String s, 여부를 테스트하는 좋은 방법이 VALUES포함은 s?



답변

Arrays.asList(yourArray).contains(yourValue)

경고 : 프리미티브 배열에는 작동하지 않습니다 (주석 참조).


이후 이제 스트림을 사용할 수 있습니다.

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

배열이 있는지 여부를 확인하기 위해 int, double또는 long값의 사용을 포함 IntStream, DoubleStream또는 LongStream각각.

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


답변

Java SE 9에 대한 간결한 업데이트

참조 배열이 잘못되었습니다. 이 경우 우리는 세트 후입니다. Java SE 9부터는 Set.of.

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

“문자열 제공, VALUES에 s가 포함되어 있는지 테스트하는 좋은 방법이 있습니까?”

VALUES.contains(s)

O (1).

적당한 유형 , 불변 , O (1)간결한 . 아름다운.*

원래 답변 세부 사항

시작하기 위해 코드를 정리하십시오. 우리는 (수정했습니다) :

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

이것은 FindBugs가 당신에게 매우 나쁜 것이라고 말할 가변 정적입니다. 정적을 수정하지 말고 다른 코드도 수정하지 마십시오. 최소한 최소한이 필드는 개인용이어야합니다.

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

(실제로 new String[];비트를 버릴 수 있습니다 .)

참조 배열은 여전히 ​​나쁘고 세트를 원합니다.

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

(나와 같은 파라노이드 사람들은 이것이 싸여 있으면 더 편하게 느낄 Collections.unmodifiableSet수 있습니다. 심지어 공개 될 수도 있습니다.)

(* 브랜드에 대해 좀 더 설명하기 위해 collections API에는 여전히 불변 컬렉션 유형이 누락되어 있으며 구문은 여전히 ​​취향에 비해 너무 장황합니다.)


답변

Apache Commons LangArrayUtils.contains 에서 사용할 수 있습니다

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

false전달 된 배열 이 인 경우이 메소드가 반환 됩니다 null.

모든 종류의 기본 배열에 사용할 수있는 메소드도 있습니다.

예:

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

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


답변

손으로 간단하게 구현하십시오.

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;
}

개량:

v != null상태에있어서 내측 일정하다. 메소드 호출 중에 항상 동일한 부울 값으로 평가됩니다. 따라서 입력 array이 크면이 조건을 한 번만 평가하는 것이 더 효율적이며 for결과에 따라 루프 내에서 단순화 / 빠른 조건을 사용할 수 있습니다. 개선 된 contains()방법 :

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;
}


답변

배열에 값이 포함되어 있는지 확인하는 4 가지 다른 방법

1) 목록 사용 :

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

2) 세트 사용 :

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

3) 간단한 루프 사용하기 :

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

4) Arrays.binarySearch () 사용 :

아래 코드가 잘못되었습니다. 완성도를 위해 여기에 나열되어 있습니다. binarySearch ()는 정렬 된 배열에서만 사용할 수 있습니다. 아래에서 결과가 이상하다는 것을 알 수 있습니다. 배열을 정렬 할 때 가장 좋은 옵션입니다.

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

빠른 예 :

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


답변

배열이 정렬되어 있지 않으면 모든 것을 반복하고 각각에 대해 동일하게 호출해야합니다.

배열이 정렬되면 이진 검색을 수행 할 수 있습니다 . Arrays 클래스에 하나가 있습니다.

일반적으로 많은 멤버쉽 확인을 수행하려는 경우 모든 항목을 배열이 아닌 세트에 저장하려고 할 수 있습니다.


답변

그만한 가치가 있기 때문에 속도에 대한 3 가지 제안을 비교 한 테스트를 실행했습니다. 임의의 정수를 생성하고 문자열로 변환하여 배열에 추가했습니다. 그런 다음 가능한 가장 높은 숫자 / 문자열을 검색했는데 이는 최악의 시나리오입니다 asList().contains().

10K 배열 크기를 사용할 때 결과는 다음과 같습니다.

정렬 및 검색 : 15
이진 검색 : 0
asList.contains : 0

100K 배열을 사용할 때 결과는 다음과 같습니다.

정렬 및 검색 : 156
이진 검색 : 0
asList.contains : 32

따라서 배열이 정렬 된 순서로 생성되면 이진 검색이 가장 빠릅니다. 그렇지 않으면 asList().contains갈 길입니다. 검색이 많은 경우 이진 검색을 사용할 수 있도록 배열을 정렬하는 것이 좋습니다. 그것은 모두 응용 프로그램에 따라 다릅니다.

나는 이것이 대부분의 사람들이 기대하는 결과라고 생각합니다. 테스트 코드는 다음과 같습니다.

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));
    }
}