문제

수백 개의 메모리 내 개체 컬렉션이 있고 쿼리와 같은 일부 SQL 또는 기준과 일치하는 개체를 반환하기 위해 이 목록을 쿼리해야 한다고 가정합니다.예를 들어, 자동차 목록 개체가 있고 1960년대에 생산된 모든 자동차를 AZ로 시작하고 자동차 모델 이름별로 정렬된 번호판을 사용하여 반환하려고 할 수 있습니다.

나는 ~에 대해 알고 있다 조SQL, 이것을 사용한 사람이 있거나 다른/자체 개발 솔루션에 대한 경험이 있습니까?

도움이 되었습니까?

해결책

나는 사용했다 아파치 커먼즈 JXPath 프로덕션 애플리케이션에서.이를 통해 Java의 개체 그래프에 XPath 표현식을 적용할 수 있습니다.

다른 팁

다른 답변에서 설명한 것처럼 필터링은 이를 수행하는 한 가지 방법입니다.

하지만 필터링은 확장 가능하지 않습니다.표면적으로 시간 복잡도는 O(N) (즉.컬렉션의 개체 수가 늘어나면 이미 확장 가능하지 않지만 실제로는 이상 쿼리에 따라 각 개체에 테스트를 적용해야 하며, 더 정확하게는 시간 복잡도는 O(n t) 어디 각 개체에 적용할 테스트 수입니다.

따라서 컬렉션에 개체가 추가되면 성능이 저하됩니다. 및/또는 쿼리의 테스트 수가 증가함에 따라.

이를 수행하는 또 다른 방법은 인덱싱 및 집합 이론을 사용하는 것입니다.

한 가지 접근 방식은 다음과 같습니다. 짓다 인덱스필드 컬렉션에 저장된 개체 내에서 나중에 쿼리에서 테스트하게 됩니다.

당신이 컬렉션을 가지고 있다고 가정 Car 사물과 모든 것 Car 객체에는 필드가 있습니다 color.귀하의 검색어가 "SELECT * FROM cars WHERE Car.color = 'blue'".다음에 색인을 구축할 수 있습니다. Car.color, 기본적으로 다음과 같습니다.

'blue' -> {Car{name=blue_car_1, color='blue'}, Car{name=blue_car_2, color='blue'}}
'red'  -> {Car{name=red_car_1, color='red'}, Car{name=red_car_2, color='red'}}

그런 다음 쿼리가 제공되었습니다. WHERE Car.color = 'blue', 파란색 자동차 세트는 O(1) 시간 복잡도.쿼리에 추가 테스트가 있는 경우 해당 항목의 각 자동차를 테스트할 수 있습니다. 후보 세트 쿼리의 나머지 테스트와 일치하는지 확인하세요.후보 세트는 전체 컬렉션보다 훨씬 작을 가능성이 높으므로 시간 복잡도는 미만 영형(N) (공학적 의미에서는 아래 설명을 참조하세요).성능이 저하되지 않습니다 만큼, 추가 객체가 컬렉션에 추가될 때.하지만 아직 완벽하지는 않습니다. 계속 읽어보세요.

또 다른 접근 방식은 제가 다음과 같이 부르는 것입니다. 스탠딩 쿼리 인덱스.설명하기:기존 반복 및 필터링을 사용하면 컬렉션이 반복되고 모든 개체가 쿼리와 일치하는지 확인하기 위해 테스트됩니다.따라서 필터링은 컬렉션에 대해 쿼리를 실행하는 것과 같습니다.고정 쿼리 인덱스는 그 반대입니다. 즉, 컬렉션이 쿼리에 대해 대신 실행되지만 컬렉션을 여러 번 쿼리할 수 있더라도 컬렉션의 각 개체에 대해 한 번만 실행됩니다.

스탠딩 쿼리 인덱스 일종의 쿼리를 등록하는 것과 같습니다. 지능형 컬렉션, 예를 들어 개체가 컬렉션에 추가되거나 제거되면 컬렉션은 등록된 모든 대기 쿼리에 대해 각 개체를 자동으로 테스트합니다.개체가 고정 쿼리와 일치하면 컬렉션은 해당 쿼리와 일치하는 개체를 저장하는 전용 세트에 개체를 추가/제거할 수 있습니다.그 후, 등록된 쿼리와 일치하는 개체는 O(1) 시간 복잡도.

위 정보는 에서 가져온 것입니다. CQEngine(컬렉션 쿼리 엔진).이는 기본적으로 컬렉션을 반복하는 오버헤드 없이 SQL과 유사한 쿼리를 사용하여 Java 컬렉션에서 개체를 검색하기 위한 NoSQL 쿼리 엔진입니다.이는 위의 아이디어와 그 이상의 아이디어를 바탕으로 구축되었습니다.부인 성명:나는 저자입니다.오픈 소스이며 Maven Central에 있습니다. 도움이 되었다면 이 답변에 찬성 투표를 해주세요!

예, 오래된 게시물이라는 것은 알고 있습니다. 하지만 기술은 매일 나타나고 대답은 시간이 지나면 바뀔 것입니다.

이 문제는 LambdaJ로 해결하면 좋은 문제라고 생각합니다.여기에서 찾을 수 있습니다:http://code.google.com/p/lambdaj/

여기에 예가 있습니다.

활성 고객 찾기 // (반복 가능한 버전)

List<Customer> activeCustomers = new ArrayList<Customer>();  
for (Customer customer : customers) {  
  if (customer.isActive()) {  
    activeCusomers.add(customer);  
  }  
}  

LambdaJ 버전

List<Customer> activeCustomers = select(customers, 
                                        having(on(Customer.class).isActive()));  

물론 이런 아름다움이 퍼포먼스에 영향을 끼치는 것은 사실입니다(조금...)평균 2회) 그런데 더 읽기 쉬운 코드를 찾을 수 있나요?

여기에는 많은 기능이 있으며 또 다른 예는 정렬일 수 있습니다.

정렬 반복

List<Person> sortedByAgePersons = new ArrayList<Person>(persons);
Collections.sort(sortedByAgePersons, new Comparator<Person>() {
        public int compare(Person p1, Person p2) {
           return Integer.valueOf(p1.getAge()).compareTo(p2.getAge());
        }
}); 

람다로 정렬

List<Person> sortedByAgePersons = sort(persons, on(Person.class).getAge()); 

계속해서 Comparator 테마를 살펴보는 것도 좋습니다. 구글 컬렉션 API.특히, 다음과 같은 인터페이스가 있습니다. 술부, 와 비슷한 역할을 하는 Comparator, 다음과 같은 필터링 방법으로 사용할 수 있는 간단한 인터페이스라는 점에서 세트.필터.여기에는 AND, OR 등을 수행하기 위한 다양한 복합 조건자 구현이 포함됩니다.

데이터 세트의 크기에 따라 SQL 또는 외부 관계형 데이터베이스 접근 방식보다 이 접근 방식을 사용하는 것이 더 합리적일 수 있습니다.

하나의 구체적인 일치 항목이 필요한 경우 클래스에서 Comparator를 구현하도록 한 다음 해시된 모든 필드가 포함된 독립형 개체를 만들고 이를 사용하여 일치 항목의 인덱스를 반환할 수 있습니다.컬렉션에서 하나 이상의 (잠재적으로) 객체를 찾으려면 JoSQL과 같은 라이브러리를 사용해야 합니다(제가 사용한 사소한 경우에는 잘 작동했습니다).

일반적으로 나는 작은 애플리케이션에도 Derby를 포함시키고, Hibernate 주석을 사용하여 내 모델 클래스를 정의하고, Hibernate가 캐싱 방식을 처리하여 모든 것을 빠르게 유지하도록 하는 경향이 있습니다.

저는 연도 범위와 자동차 번호판 패턴을 입력 매개변수로 사용하는 비교기를 사용하겠습니다.그런 다음 컬렉션을 반복하고 일치하는 개체를 복사하세요.이 접근 방식을 사용하면 사용자 정의 비교기의 전체 패키지를 만들 수 있습니다.

그만큼 Comparator 옵션은 나쁘지 않습니다. 특히 익명 클래스를 사용하는 경우(프로젝트에서 중복 클래스를 생성하지 않기 위해), 결국 비교 흐름을 살펴보면 전체 컬렉션을 직접 반복하여 정확히 지정하는 것과 거의 같습니다. 아이템 매칭 조건:

if (Car car : cars) {
    if (1959 < car.getYear() && 1970 > car.getYear() &&
            car.getLicense().startsWith("AZ")) {
        result.add(car);
    }
}

그 다음은 정렬...뒷모습이 아플 수도 있지만 다행히도 수업이 있어 Collections 그리고 그것의 sort 메서드 중 하나는 Comparator...

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top