In Java 8 how do I transform a Map to another Map using a lambda?

前端 未结 7 1120
悲&欢浪女
悲&欢浪女 2020-12-02 14:01

I\'ve just started looking at Java 8 and to try out lambdas I thought I\'d try to rewrite a very simple thing I wrote recently. I need to turn a Map of String to Column int

相关标签:
7条回答
  • 2020-12-02 14:28

    If you use Guava (v11 minimum) in your project you can use Maps::transformValues.

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

    Note: The values of this map are evaluated lazily. If the transformation is expensive you can copy the result to a new map like suggested in the Guava docs.

    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.
    
    0 讨论(0)
  • 2020-12-02 14:28

    If you don't mind using 3rd party libraries, my cyclops-react lib has extensions for all JDK Collection types, including Map. You can directly use the map or bimap methods to transform your Map. A MapX can be constructed from an existing Map eg.

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

    If you also wish to change the key you can write

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

    bimap can be used to transform the keys and values at the same time.

    As MapX extends Map the generated map can also be defined as

      Map<String, Column> y
    
    0 讨论(0)
  • 2020-12-02 14:35

    The way without re-inserting all entries into the new map should be the fastest it won't because HashMap.clone internally performs rehash as well.

    Map<String, Column> newColumnMap = originalColumnMap.clone();
    newColumnMap.replaceAll((s, c) -> new Column(c));
    
    0 讨论(0)
  • 2020-12-02 14:37

    Here is another way that gives you access to the key and the value at the same time, in case you have to do some kind of transformation.

    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));
    
    0 讨论(0)
  • 2020-12-02 14:38

    You could use a 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) {}
      }
    }
    
    0 讨论(0)
  • 2020-12-02 14:43

    Keep it Simple and use 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())
                                      );
    
    0 讨论(0)
提交回复
热议问题