2016-10-14 4 views
0

나는 중첩 된 값을 가진 json 구조가 커서 작업 할 개체 목록으로 변환되었습니다. 특정 속성 값을 포함하지 않는 모든 개체를 필터링하고 싶습니다. 문제는, 지금까지 제가 생각해 낸 것은 for 루프 내의 for 루프 내의 for 루프입니다. 그리고 이것은 json 구조가 단지 3 개의 중첩 된 레벨이라는 것을 알고 있습니다. 정수 만 포함하는 객체 만 필터링하려고합니다 (null 인 경우, 유효한 무언가를 포함하는 부모 일 수도 있고 비어있는 부모 일 수도 있음). 병합으로 스트리밍하려고하면 모든 객체와 중첩 된 객체를 필터링 할 수 있지만 구조를 잃지는 않습니까?자체 순환 참조가있는 개체 필터링 (ObjectA에는 List <ObjectA> 속성이 있습니다.)

예 :

public class ObjectA { 
Integer id; 
List<ObjectA> sublist; 
} 


List<ObjectA> fullList; 
Set<Integer> keeptheseIntegers; 
for (ObjectA obj : fullList) { 
    if (obj.getId() != null && !keeptheseIntegers.contains(obj.getId()){ 
    fullList.remove(obj); 
    } else if (obj.getId() == null && obj.getSubList().size() > 0) { 
    for (ObjectA subObj : obj.getSubList()){ 
    (same thing as above) 
    } 
} 

편집 - 나중에 제거가 제대로 작동하지 않고 iterator.remove를 사용했다는 것을 깨달았습니다. 여전히 논리적 인 문제 임

+0

당신이 ObjectA가 유효한 정수 또는 유효한 하위 목록 중 하나를 포함 뜻 이죠,하지만 둘 : 메인 프로그램

public class ObjectA { Integer id; List<ObjectA> sublist; } private static final Set<Integer> keeptheseIntegers = new HashSet<>(); static { keeptheseIntegers.add(1); } private List<ObjectA> filter(List<ObjectA> list) { List<List<ObjectA>> subLists = new ArrayList<>(); List<ObjectA> result = list.stream() // get all objects with sublist and add the sublist to interim subLists: .peek(obj -> { if (obj.sublist == null) { // assert your assumption that Integer is assigned if (obj.id == null) { throw new IllegalArgumentException(); } } else { subLists.add(obj.sublist); } }) // filter for the objects you want in result: .filter((obj -> obj.id != null && keeptheseIntegers.contains(obj.id))) // and convert the resulting stream to a list: .collect(Collectors.toList()); // call this method recusively for all found sublists: subLists.forEach(i -> result.addAll(filter(i))); return result; } 

및 somewher 당신이 그것을 호출 흐름 ? – Heri

+0

fullList.remove (obj)는 자체 iterator 내에서 콜렉션을 변경할 수 없기 때문에 예외를 throw한다고 가정합니다. – Heri

+0

네 haha ​​내가 iterator.remove하지만 루프 등 루프 내에서 올바른 노드가 유효한 정수/sublist에 관한 올바른 올바른 것 같아요. . – ec3

답변

0

첫 번째 : 원래 구조를 조작하는 대신 (원하지 않는 항목 제거) 알고리즘 중에 원하는 항목을 자체 목록으로 수집합니다.

두 번째 : 중첩 구조를 통한 반복은 재귀 패턴의 좋은 후보입니다.

3 차 : 자바 8을 사용하여 스트림과 람다를 사용하여 구현했습니다.

이런 식으로 뭔가 :

... 
List<ObjectA> fullList = new ArrayList<>(); 
List<ObjectA> objWithInt = filter(fullList); 
// process the received list. Your original fullList is unchanged. 
+0

Hey @Heri는 응답 지연에 대한 제안과 사과에 감사드립니다. 그러나 생성 된 목록이 전혀 중첩되어 있지 않은 것 같습니다. 따라서 결과는 계층화 된 목록과 계층을 포함하는 목록 일뿐입니다 – ec3