1. 개요

List에서 요소를 찾는 것은 개발자로서 접하게되는 매우 일반적인 작업입니다.

여기에서는 Java로 이것을 수행 할 수있는 다양한 방법에 대해 설명합니다.

2. 설정

먼저 고객 POJO 를 정의하여 시작하겠습니다 .

public class Customer {

    private int id;
    private String name;
    
    // getters/setters, custom hashcode/equals
}

그런 다음 고객 ArrayList :

List<Customer> customers = new ArrayList<>();
customers.add(new Customer(1, "Jack"));
customers.add(new Customer(2, "James"));
customers.add(new Customer(3, "Kelly"));

우리는 고객 클래스  에서 hashCode  와 같음재정의했습니다 .

현재의 equals 구현을 기반으로 동일한 ID가진 두 개의 Customer 객체가 동일한 것으로 간주됩니다.

고객 List을 사용합니다  .

3. Java API 사용

Java 자체는 List에서 항목을 찾는 여러 가지 방법을 제공합니다.

  • 는  포함 방법
  • 같이 IndexOf의  방법
  • 임시 for 루프
  • 스트림  API

3.1. contains ()

List  는 contains 라는 메서드를 노출합니다  .

boolean contains(Object element)

이름에서 알 수 있듯이이 메서드는 List에 지정된 요소 가 포함되어 있으면 true를  반환 하고 그렇지 않으면 false를 반환합니다. 

따라서 List에 특정 항목이 있는지 확인해야 할 때 다음을 수행 할 수 있습니다.

Customer james = new Customer(2, "James");
if (customers.contains(james)) {
    // ...
}

3.2. indexOf ()

indexOf  는 요소를 찾는 또 다른 유용한 방법입니다.

int indexOf(Object element)

이 메서드는 주어진 List에서 지정된 요소 의 첫 번째 발생 인덱스를 반환 하거나 List에 요소가 포함되지 않은 경우 -1을 반환합니다 .

따라서 논리적으로이 메서드가 -1이 아닌 다른 값을 반환하면 List에 요소가 포함되어 있음을 알 수 있습니다.

if(customers.indexOf(james) != -1) {
    // ...
}

이 방법을 사용하는 가장 큰 장점은 주어진 List에서 지정된 요소의 위치를 ​​알 수 있다는 것입니다.

3.3. 기본 루핑

이제 요소에 대한 필드 기반 검색을 수행하려면 어떻게해야합니까? 예를 들어, 복권을 발표 하고 특정 이름고객당첨자로 선언해야한다고 가정 해 보겠습니다 .

이러한 필드 기반 검색의 경우 반복으로 전환 할 수 있습니다.

List을 반복하는 전통적인 방법은 Java의 반복 구조 중 하나를 사용하는 것입니다 . 반복 할 때마다 List의 현재 항목을 찾고있는 요소와 비교하여 일치하는지 확인합니다.

public Customer findUsingEnhancedForLoop(
  String name, List<Customer> customers) {

    for (Customer customer : customers) {
        if (customer.getName().equals(name)) {
            return customer;
        }
    }
    return null;
}

여기서 이름 은 주어진 고객 List에서 검색 하는 이름을 나타냅니다 . 이 메서드는 일치하는 이름을 가진 List 의 첫 번째 Customer 개체를 반환 하거나 해당 Customer없는 경우 null을 반환 합니다.

3.4. 반복자로 루핑

반복기  는 항목 List을 탐색 할 수있는 또 다른 방법입니다.

이전 예제를 사용하여 약간 조정할 수 있습니다.

public Customer findUsingIterator(
  String name, List<Customer> customers) {
    Iterator<Customer> iterator = customers.iterator();
    while (iterator.hasNext()) {
        Customer customer = iterator.next();
        if (customer.getName().equals(name)) {
            return customer;
        }
    }
    return null;
}

결과적으로 동작은 이전과 동일합니다.

3.5. 자바 8 스트림 API

Java 8부터는 Stream API  를 사용하여 List 에서 요소를 찾을 수도  있습니다 .

주어진 List에서 특정 기준과 일치하는 요소를 찾으려면 다음을 수행합니다.

  • List에서 stream () 호출
  •  적절한 술어로 f ilter () 메소드를 호출하십시오. 
  •  해당 요소가 존재하는 경우 Optional에 래핑 된 필터 조건 자 와 일치하는 첫 번째 요소  를 반환 하는 findAny ()  구성을 호출  합니다.
Customer james = customers.stream()
  .filter(customer -> "James".equals(customer.getName()))
  .findAny()
  .orElse(null);

편의를 위해 Optional 이 비어 있는 경우 기본값은 null 이지만 모든 시나리오에 대해 항상 최선의 선택은 아닙니다.

4. 타사 라이브러리

이제 Stream API로 충분하지만 이전 버전의 Java를 사용하는 경우 어떻게해야합니까?

다행히도 사용할 수있는 Google Guava 및 Apache Commons와 같은 타사 라이브러리가 많이 있습니다.

4.1. Google 구아바

Google Guava는 스트림으로 수행 할 수있는 작업과 유사한 기능을 제공합니다.

Customer james = Iterables.tryFind(customers,
  new Predicate<Customer>() {
      public boolean apply(Customer customer) {
          return "James".equals(customer.getName());
      }
  }).orNull();

Stream API 와 마찬가지로 선택적으로 null 대신 기본값을 반환하도록 선택할 수 있습니다 .

Customer james = Iterables.tryFind(customers,
  new Predicate<Customer>() {
      public boolean apply(Customer customer) {
          return "James".equals(customer.getName());
      }
  }).or(customers.get(0));

위의 코드는 일치하는 항목이 없으면 List에서 첫 번째 요소를 선택합니다.

또한 Guava는 List 또는 술어가 null 인 경우 NullPointerException을 던진다는 것을 잊지 마십시오 .

4.2. Apache Commons

Apache Commons를 사용하여 거의 동일한 방법으로 요소를 찾을 수 있습니다.

Customer james = IterableUtils.find(customers,
  new Predicate<Customer>() {
      public boolean evaluate(Customer customer) {
          return "James".equals(customer.getName());
      }
  });

하지만 몇 가지 중요한 차이점이 있습니다.

  1. 아파치 코 몬즈는 반환 널을  우리가 통과하면 리스트.
  2. 그것은  구아바의 같은 기본 값 기능을 제공하지 않습니다 tryFind합니다.

5. 결론

이 기사에서 우리는 List 에서 요소를 찾고, 빠른 존재 여부를 확인하고, 필드 기반 검색으로 마무리 하는 다양한 방법을 배웠습니다 .

또한 Java 8 Streams API의 대안으로 타사 라이브러리 인 Google GuavaApache Commons살펴 보았습니다  .

들러 주셔서 감사합니다 . GitHub 에서이 예제 대한 모든 소스를 확인하세요 .