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());
}
});
하지만 몇 가지 중요한 차이점이 있습니다.
- 아파치 코 몬즈는 반환 널을 우리가 통과하면 널 리스트.
- 그것은 구아바의 같은 기본 값 기능을 제공하지 않습니다 tryFind합니다.
5. 결론
이 기사에서 우리는 List 에서 요소를 찾고, 빠른 존재 여부를 확인하고, 필드 기반 검색으로 마무리 하는 다양한 방법을 배웠습니다 .
또한 Java 8 Streams API의 대안으로 타사 라이브러리 인 Google Guava 및 Apache Commons 를 살펴 보았습니다 .