속성으로 ArrayList에서 개체를 찾는 방법


83

어떻게 개체를 찾을 수 있습니다 CarnetA의, ArrayList<Carnet>알고 그 특성 codeIsin.

List<Carnet> listCarnet = carnetEJB.findAll();

public class Carnet {

    private String codeTitre;
    private String nomTitre;
    private String codeIsin;

    // Setters and getters

}

4
와 함께 indexOf(), 객체가 equals().
jlordo

클래스 카르네 내부 항아리 내가 등호를 재정의 할 수 없습니다 파일 ()입니다

1
내가 당신이라면 어디서든 소스 코드를 찾아서 같고 hashCode를 구현할 것입니다. 유일한 다른 대안은 컬렉션을 수동으로 반복하고 구성원이 같은지 확인하는 것입니다.
Thihara 2013-07-08

차라리 목록 대신지도를 사용하고 싶습니다. 개체를 자주 찾고 성능이 문제가되는 경우 정렬 된 맵이 더 좋을 수 있습니다. 이 목적을 위해 동등하게 구현하고 사용하는 것은 내 관점에서 추악합니다.
mmirwaldt 2013

2
Java 8의 경우 ArrayList에서 스트림을 가져와 filter (e-> e.codeIsIn.equals (...))를 적용 할 수 있습니다.
Thorbjørn Ravn Andersen 2016 년

답변:


79

반복 없이는 할 수 없습니다.

옵션 1

Carnet findCarnet(String codeIsIn) {
    for(Carnet carnet : listCarnet) {
        if(carnet.getCodeIsIn().equals(codeIsIn)) {
            return carnet;
        }
    }
    return null;
}

옵션 2

equals()메서드를 재정의합니다 Carnet.

옵션 3

당신의 저장 ListA와 Map사용하는 대신 codeIsIn키로 :

HashMap<String, Carnet> carnets = new HashMap<>();
// setting map
Carnet carnet = carnets.get(codeIsIn);

8
나는 Option2를 얻지 못한다. 나는 무시 equals()하고 무엇을합니까?
large_prime_is_463035818

@ idclev463035818 내가 사용을 추측하고 ArrayList.indexOf방법
Moosefeather

76

Java8 에서는 스트림을 사용할 수 있습니다.

public static Carnet findByCodeIsIn(Collection<Carnet> listCarnet, String codeIsIn) {
    return listCarnet.stream().filter(carnet -> codeIsIn.equals(carnet.getCodeIsin())).findFirst().orElse(null);
}

또한 여러 다른 객체 (뿐만 아니라 Carnet)가 있거나 다른 속성 (뿐만 아니라 cideIsin) 으로 찾으려면 유틸리티 클래스를 빌드하여이 논리를 캡슐화 할 수 있습니다.

public final class FindUtils {
    public static <T> T findByProperty(Collection<T> col, Predicate<T> filter) {
        return col.stream().filter(filter).findFirst().orElse(null);
    }
}

public final class CarnetUtils {
    public static Carnet findByCodeTitre(Collection<Carnet> listCarnet, String codeTitre) {
        return FindUtils.findByProperty(listCarnet, carnet -> codeTitre.equals(carnet.getCodeTitre()));
    }

    public static Carnet findByNomTitre(Collection<Carnet> listCarnet, String nomTitre) {
        return FindUtils.findByProperty(listCarnet, carnet -> nomTitre.equals(carnet.getNomTitre()));
    }

    public static Carnet findByCodeIsIn(Collection<Carnet> listCarnet, String codeIsin) {
        return FindUtils.findByProperty(listCarnet, carnet -> codeIsin.equals(carnet.getCodeIsin()));
    }
}

2

다음은 Guava를 사용하는 솔루션입니다.

private User findUserByName(List<User> userList, final String name) {
    Optional<User> userOptional =
            FluentIterable.from(userList).firstMatch(new Predicate<User>() {
                @Override
                public boolean apply(@Nullable User input) {
                    return input.getName().equals(name);
                }
            });
    return userOptional.isPresent() ? userOptional.get() : null; // return user if found otherwise return null if user name don't exist in user list
}

2

Java 8 을 사용 하고 검색에서 null이 반환 될 수있는 경우 Optional 클래스를 사용해 볼 수 있습니다.

카르네를 찾으려면 :

private final Optional<Carnet> findCarnet(Collection<Carnet> yourList, String codeIsin){
    // This stream will simply return any carnet that matches the filter. It will be wrapped in a Optional object.
    // If no carnets are matched, an "Optional.empty" item will be returned
    return yourList.stream().filter(c -> c.getCodeIsin().equals(codeIsin)).findAny();
}

이제 사용법 :

public void yourMethod(String codeIsin){
    List<Carnet> listCarnet = carnetEJB.findAll();

    Optional<Carnet> carnetFound = findCarnet(listCarnet, codeIsin);

    if(carnetFound.isPresent()){
        // You use this ".get()" method to actually get your carnet from the Optional object
        doSomething(carnetFound.get());
    }
    else{
        doSomethingElse();
    }
}

2

다음은 Java 8 에서 Guava 를 사용 하여 목록에있는 경우 일치하는 요소를 반환하는 또 다른 솔루션 입니다. 둘 이상의 요소가 일치하면 수집기는 IllegalArgumentException을 발생시킵니다. 널 (null)이 일치가없는 경우 반환됩니다.

Carnet carnet = listCarnet.stream()
                    .filter(c -> c.getCodeIsin().equals(wantedCodeIsin))
                    .collect(MoreCollectors.toOptional())
                    .orElse(null);

0

Oleg 답변 에 따라 속성으로 필터링 된 List의 모든 개체 를 찾으려면 다음과 같이 할 수 있습니다.

//Search into a generic list ALL items with a generic property
public final class SearchTools {
       public static <T> List<T> findByProperty(Collection<T> col, Predicate<T> filter) {
           List<T> filteredList = (List<T>) col.stream().filter(filter).collect(Collectors.toList());
           return filteredList;
     }

//Search in the list "listItems" ALL items of type "Item" with the specific property "iD_item=itemID"
public static final class ItemTools {
         public static List<Item> findByItemID(Collection<Item> listItems, String itemID) {
             return SearchTools.findByProperty(listItems, item -> itemID.equals(item.getiD_Item()));
         }
     }
}

유사하게 특정 속성으로 HashMap의 모든 항목 을 필터링하려는 경우

//Search into a MAP ALL items with a given property
public final class SearchTools {
       public static <T> HashMap<String,T> filterByProperty(HashMap<String,T> completeMap, Predicate<? super Map.Entry<String,T>> filter) {
           HashMap<String,T> filteredList = (HashMap<String,T>) completeMap.entrySet().stream()
                                .filter(filter)
                                .collect(Collectors.toMap(map -> map.getKey(), map -> map.getValue()));
           return filteredList;
     }

     //Search into the MAP ALL items with specific properties
public static final class ItemTools {

        public static HashMap<String,Item> filterByParentID(HashMap<String,Item> mapItems, String parentID) {
            return SearchTools.filterByProperty(mapItems, mapItem -> parentID.equals(mapItem.getValue().getiD_Parent()));
        }

        public static HashMap<String,Item> filterBySciName(HashMap<String,Item> mapItems, String sciName) {
            return SearchTools.filterByProperty(mapItems, mapItem -> sciName.equals(mapItem.getValue().getSciName()));
        }
    }

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.