programing

Java 8에서 Lamda를 사용하여 Map을 다른 Map으로 변환하려면 어떻게 해야 합니까?

shortcode 2022. 7. 17. 20:56
반응형

Java 8에서 Lamda사용하여 Map다른 Map으로 변환하려면 어떻게 해야 합니까?

Java 8을 막 살펴보기 시작했는데 람다를 먹어보려고 최근에 쓴 아주 간단한 글을 다시 쓰려고 했어요.스트링 투 컬럼 맵을 다른 스트링 투 컬럼 맵으로 변환해야 합니다.여기서 새 맵의 컬럼은 첫 번째 맵의 컬럼의 방어 복사본입니다.열에 복사 생성자가 있습니다.내가 지금까지 알아낸 가장 가까운 건

    Map<String, Column> newColumnMap= new HashMap<>();
    originalColumnMap.entrySet().stream().forEach(x -> newColumnMap.put(x.getKey(), new Column(x.getValue())));

더 좋은 방법이 있을 거라고 확신하고 조언해주시면 감사하겠습니다.

Collector를 사용할 수 있습니다.

import java.util.*;
import java.util.stream.Collectors;

public class Defensive {

  public static void main(String[] args) {
    Map<String, Column> original = new HashMap<>();
    original.put("foo", new Column());
    original.put("bar", new Column());

    Map<String, Column> copy = original.entrySet()
        .stream()
        .collect(Collectors.toMap(Map.Entry::getKey,
                                  e -> new Column(e.getValue())));

    System.out.println(original);
    System.out.println(copy);
  }

  static class Column {
    public Column() {}
    public Column(Column c) {}
  }
}
Map<String, Integer> map = new HashMap<>();
map.put("test1", 1);
map.put("test2", 2);

Map<String, Integer> map2 = new HashMap<>();
map.forEach(map2::put);

System.out.println("map: " + map);
System.out.println("map2: " + map2);
// Output:
// map:  {test2=2, test1=1}
// map2: {test2=2, test1=1}

를 사용할 수 있습니다.forEach원하는 것을 할 수 있는 방법.

여기서 하는 일은 다음과 같습니다.

map.forEach(new BiConsumer<String, Integer>() {
    @Override
    public void accept(String s, Integer integer) {
        map2.put(s, integer);     
    }
});

람다로 단순화 할 수 있습니다.

map.forEach((s, integer) ->  map2.put(s, integer));

기존 메서드를 호출하는 것뿐이므로 메서드 참조를 사용하면 다음과 같은 이점이 있습니다.

map.forEach(map2::put);

단순성 유지 및 Java 8 사용:-

 Map<String, AccountGroupMappingModel> mapAccountGroup=CustomerDAO.getAccountGroupMapping();
 Map<String, AccountGroupMappingModel> mapH2ToBydAccountGroups = 
              mapAccountGroup.entrySet().stream()
                         .collect(Collectors.toMap(e->e.getValue().getH2AccountGroup(),
                                                   e ->e.getValue())
                                  );

모든 엔트리를 새 맵에 다시 삽입하지 않는 방법이 가장 빠릅니다.HashMap.clone내부에서도 리해시를 수행합니다.

Map<String, Column> newColumnMap = originalColumnMap.clone();
newColumnMap.replaceAll((s, c) -> new Column(c));

프로젝트에서 Guava(v11 최소값)를 사용하는 경우 Maps:: transformValues를 사용할 수 있습니다.

Map<String, Column> newColumnMap = Maps.transformValues(
  originalColumnMap,
  Column::new // equivalent to: x -> new Column(x) 
)

주의: 이 맵의 값은 느슨하게 평가됩니다.변환 비용이 많이 드는 경우 결과를 Guava 문서에서 제시된 새 맵에 복사할 수 있습니다.

To avoid lazy evaluation when the returned map doesn't need to be a view, copy the returned map into a new map of your choosing.

다음은 변환 작업을 수행해야 하는 경우에 대비하여 키와 값에 동시에 액세스할 수 있는 또 다른 방법입니다.

Map<String, Integer> pointsByName = new HashMap<>();
Map<String, Integer> maxPointsByName = new HashMap<>();

Map<String, Double> gradesByName = pointsByName.entrySet().stream()
        .map(entry -> new AbstractMap.SimpleImmutableEntry<>(
                entry.getKey(), ((double) entry.getValue() /
                        maxPointsByName.get(entry.getKey())) * 100d))
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));

서드파티 라이브러리를 사용해도 괜찮으시다면 my cyclops-react lib에는 Map을 포함모든 JDK 컬렉션 유형에 대한 확장 기능이 있습니다.지도 또는 바이맵 방법을 직접 사용하여 지도를 변환할 수 있습니다.MapX는 기존 Map에서 구성할 수 있습니다.

  MapX<String, Column> y = MapX.fromMap(orgColumnMap)
                               .map(c->new Column(c.getValue());

키도 변경하고 싶은 경우는, 기입할 수 있습니다.

  MapX<String, Column> y = MapX.fromMap(orgColumnMap)
                               .bimap(this::newKey,c->new Column(c.getValue());

bimap을 사용하여 키와 값을 동시에 변환할 수 있습니다.

MapX가 Map을 확장함에 따라 생성된 맵도 다음과 같이 정의할 수 있습니다.

  Map<String, Column> y

언급URL : https://stackoverflow.com/questions/22742974/in-java-8-how-do-i-transform-a-mapk-v-to-another-mapk-v-using-a-lambda

반응형