2017-11-27 9 views
1

현재 객체의 arraylist에 참석하는 것을 포함하는 구현을 위해 노력하고 있습니다 (예 : 1000). 속성에 공통점을 찾아 그룹화합니다. 등록, 위치 년, 양거대한 컬렉션에서 유사한 객체를 트래버스하고 그룹화하는 효율적인 방법

그룹화 기준 - -

ArrayList itemList<CustomJaxbObj> = {Obj1,obj2,....objn} //n can reach to 1000 

개체 속성 예를 들어

등록 번호 및 위치 같은 해에 개체에 대한 ... 양을 추가

하는 경우 10 개의 객체가 있는데, 8 개의 객체가 동일한 loc와 year의 등록을 가지고 있고, 8 개 모두와 reg와 loc가 일치하는 다른 2 개의 금액을 더합니다. 따라서 작업이 끝나면 2 개의 객체가 남았습니다. 1은 일치 된 8 개의 객체의 합계이고 1은 객체의 2 개의 일치 기준입니다.

현재 이중 전통 루프를 사용하고 있습니다. 고급 루프가 더 좋지만 그룹화를 수행해야하는 인덱스에 대한 제어가 많지 않습니다. 그것은 그룹화 된 엔트리의 새로운 엔트리를 형성하기 위해 결합 된 개별 엔트리를 추적 할 수있게 해줍니다.

for (i = 0; i < objlist.size(); i++) { 
    for(j = i+1; j< objList.size();j++){ 
    //PErform the check with if/else condition and traverse the whole list 
    } 
} 

이 작업은 매우 비효율적이며 무거운 작업입니다. 이 작업을 수행하는 더 좋은 방법이 있습니까? Java8 스트림을 사용하도록 다른 답변을 보았지만 작업이 복잡하므로 그룹화를 수행해야합니다. 나는 성냥이있을 때 무언가를하는보기를 주었다 그러나 다만 추가에 그것보다는 더 많은 것이있다.

더 나은 방법이 있습니까? 검색 및 그룹화를 더 쉽게하는 이런 종류의 데이터를 보유하는 더 나은 데이터 구조?

더 많은 관점을 추가하면 이전에이 정보를 제공하지 않았던 것에 사과드립니다.

arraylist는 수신 페이로드 xml의 jaxb 개체 모음입니다.

XML 계층 구조

<Item> 
<Item1> 
    <Item-Loc/> 
    <ItemID> 
    <Item-YearofReg/> 
    <Item-Details> 
     <ItemID/> 
     <Item-RefurbishMentDate> 
     <ItemRefurbLoc/> 
    </Item-Details> 
</Item1> 
<Item2></Item2> 
<Item3></Item3> 
.... 
</Item> 

그래서 항목의 JAXB 객체는 900-1000 항목의 목록이 있습니다. 각 품목에는 개장 날짜가있는 ItemDetails의 하위 섹션이있을 수 있습니다. 내가 직면 한 문제는 Item Details 섹션이 없을 때 이중 루프가 잘 작동하며 모든 항목을 탐색하고 확인할 수 있다는 것입니다. 요구 사항에 따르면 제품을 리퍼브 한 경우 해당 연도를 간과하고 대신 기준을 충족시키는 재 설계 연도를 고려합니다.

또 다른 요점은 Item1의 항목 세부 정보가 Item2 Item Details 섹션에 나타날 수있는 섹션의 동일한 Item에 속할 필요가 없다는 것입니다. Item id는 올바른 항목을 항목 세부 정보에 매핑하는 데 사용하는 필드입니다 .

전체 목록을 읽지 않으면 변경을 시작할 수 없습니다. 루프의 정상적인 무언가가 그것을 할 것이지만 이중 루프 때문에 이미 증가한 순환 복잡성을 증가시킬 것입니다.

따라서 그룹화를 수행하기 전에 먼저 개체 목록을 저장하고 분석하기위한 데이터 구조가 필요합니다.

죄송합니다. stackoverflow 내 첫 질문, 따라서 경험이 없습니다.

+0

현재 개체를 저장하는 데 사용하는 누적 계산기의 예를 표시 할 수 있습니까? –

+0

질문에 대한 더 많은 통찰력이 추가되었습니다. 현재 ArrayList에 모든 내용을 저장하고 기준이 일치 할 때 작업을 수행합니다. –

답변

0

당신은 등록 및 위치 최종 목표는하지만, 여기에 당신이 시작하는 것이 무엇인지

1

100 % 확인의 같은 해를 가지는 요소의 양을 추가하는 해시를 사용할 수 있습니다. 같은 두 가지 속성에 의해 그룹에, 당신이 뭔가를 할 수 있습니다

Map<String, Map<Integer, List<MyObjectType>>> map = itemList.stream() 
       .collect(Collectors.groupingBy(MyObjectType::getLoc, 
         Collectors.groupingBy(MyObjectType::getYear))); 

솔루션은 위의 getLocStringgetYear이 유형 Integer하는 유형입니다 가정, 당신은 당신이 원하는 금액을 얻기 위해 더 스트림 작업을 수행 할 수 있습니다.

+0

이것은 맵의 맵을 생성합니다. OP는 그룹화 된 단일 키를 찾습니다. – Eugene

+0

이것은 도움이 될 수 있지만 최근에 알아야 할 새로운 요구 사항이 있습니다. 질문을 조금 업데이트했습니다. 사과. JAVA8 컨베이어 벨트 방식을 사용하면이 작업을보다 효율적으로 수행 할 수 있습니다. –

+0

@KarthikRK는 나를 잘못 이해하지는 못했지만 편집 내용에 약간의 설명이 필요했으나 문제가 더 심각해졌습니다. 나는 그것을 지금 세 번 읽고 여전히 당신의 문제가 무엇인지 말할 수 없다. – Eugene

0

Collectors.groupingBy(classifier, downstream)Collectors.summingInt을 다운 스트림 수집기로 사용할 수 있습니다. 내 물건을 정의하기 위해 휴가를 가져 가려고 물건의 클래스를 게시하지 않았다. 그러나 그 아이디어는 비슷합니다. 또한 AbstractMap.SimpleEntry을 최종지도의 핵심으로 사용했습니다.

import java.util.AbstractMap; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Map; 
import java.util.stream.Collectors; 

public class GroupByYearAndLoc { 
    static class Node { 
     private Integer year; 
     private String loc; 
     private int value; 

     Node(final Integer year, final String loc, final int value) { 
      this.year = year; 
      this.loc = loc; 
      this.value = value; 
     } 
    } 

    public static void main(String[] args) { 
     List<Node> nodes = new ArrayList<>(); 
     nodes.add(new Node(2017, "A", 10)); 
     nodes.add(new Node(2017, "A", 12)); 
     nodes.add(new Node(2017, "B", 13)); 
     nodes.add(new Node(2016, "A", 10)); 

     Map<AbstractMap.SimpleEntry<Integer, String>, Integer> sums = nodes.stream() 
       // group by year and location, then sum the value. 
       .collect(Collectors.groupingBy(n-> new AbstractMap.SimpleEntry<>(n.year, n.loc), Collectors.summingInt(x->x.value))); 
     sums.forEach((k, v)->{ 
      System.out.printf("(%d, %s) = %d\n", k.getKey(), k.getValue(), v); 
     }); 
    } 
} 

그리고 출력 :

(2017, A) = 22 
(2016, A) = 10 
(2017, B) = 13 
+0

스트림은 내가 취해야 할 가능성이있는 도로처럼 보입니다. 당신의 대답은 사고 과정에서 도움이됩니다. 나는 최근에 추가 한 새로운 요구 사항을 수용해야한다고 생각해야한다. 하지만 고마워! –

0

내가 "년 + 위치"를 만들 것은 해시 맵의 키, 그리고 각 고유 키와 관련된 어떤 것을지도 보류하게 연결된. 그런 다음 하나의 "for 루프"만 가질 수 있습니다 (중첩 루프가 아님). 이것이 가장 간단한 방법입니다.