스트림을 사용하여 너무 우아하지 않은 코드를 리펙토링하려고합니다. 내가 HashMap의 문자열과 MyObjects를 포함, 현재과 같이 루프를 사용하여 반복 있습니다스트림을 사용하여 그룹화를 기반으로 컬렉션에서 두 가지 기능을 수행하려면 어떻게해야합니까?
Map<String, MyObject> map = new HashMap<>();
Map<String, MyObject> objectsToAdd = new HashMap<>();
for(MyObject object : map.values()){
String idToAdd = object.getConnectedToId();
if(StringUtils.isEmpty(idToAdd) {
continue;
}
if(idToAdd.substring(0,1).equals("i")){ // connected to an ICS
MyObject newObject = service1.someMethod(idToAdd);
if(newObject != null) {
objectsToAdd.put(newObject.getId(), newObject);
}
} else if (idToAdd.substring(0,1).equals("d")){ // connected to a device
MyObject newObject = service2.someMethod(idToAdd);
if(newObject != null) {
objectsToAdd.put(newObject.getId(), newObject);
}
}
}
map.putAll(objectsToAdd);
나는 단지 ID에 대한 걱정 때문에를, 나는 뒤에 만 ID를 얻기 위해지도 작업을 사용하여 시작 빈 것을 제거하는 필터 조작.
다음 부분은 내가 문제가되는 부분입니다. 이 링크는 스트림 수집을 사용 감소에 도움이
map.values().stream()
.map(myObject -> myObject.getConnectedToId()) // get a map of all the ids
.filter(StringUtils::isNotEmpty) // filter non empty ones
.collect(
Collectors.mapping(
MyObject::getId,
Collectors.toList())),
Collectors.groupingBy(
s -> s.substring(0,1));
: 나는 ID의 첫 번째 문자를 기반으로 항목과 나는이와 결국 그룹 수 나는 수집기, groupingBy 작업을 사용하여 한 시도 우선 그래서 : Stream Reduction
이 코드에는 적어도 다음 두 가지 문제가 있습니다. 1) 수집은 스트림을 닫고 아직 완료하지 않았으며 2) 원래 개체가 필요하지만 이제는 connectedToIds의 map입니다.
Q1) ID의 첫 문자를 기준으로 개체를 그룹화 할 수있는 중간 작업이 있습니까?
Q2) 컬렉션을 ID로만 줄이지 않고 어떻게 할 수 있습니까?
Q3) 그리고 마지막으로 컬렉션이 그룹화되면 (두 개가 될 것입니다.) 원래 코드에서와 같이 각 그룹별로 어떻게 별도의 기능을 수행 할 수 있습니까?
최종 솔루션 (덕분에 도움을 & @Flown을 @Holger하기는)
Map<Character, Function<String, MyObejct>> methodMapping = new HashMap<>();
methodMapping.put('i', service1::method1);
methodMapping.put('d', service2::method2);
Map<String, MyObject> toAdd = map.values().stream().map(MyObject::getConnectedToId)
.filter(StringUtils::isNotEmpty)
.map(id -> methodMapping.getOrDefault(id.charAt(0), i -> null).apply(id))
.filter(Objects::nonNull)
.collect(Collectors.toMap(MyObject::getId, Function.identity(), (mo1, mo2) -> mo2));
map.putAll(toAdd);
동시 수정 예외를 방지하기 위해, 먼저 저장소에 임시 맵에있는 오브젝트를 수행하는 동안 필요 스트림 작업을 완료 한 다음 최종 맵에 추가하십시오.
지도의 키가 'MyObject'의 'id'라고 가정합니다. 나는. – Flown
예, HashMap의 키는 MyObject의 ID입니다. 명확성을 위해 질문에 대한 사소한 편집을했습니다. idToAdd는 객체의 ID가 아니라 myObject의 connectedToId입니다. – Kristina