Java 8 Map 循环,排序,合并(merge)
2020-09-03  本文已影响0人 
xiaogp
摘要:JAVA Map,forEach,entrySet,Comparator,stream,merge
循环
- (1)使用
entrySet转化为映射或者直接使用forEach循环 
for (Map.Entry<String, Double> items : myMap.entrySet()) {
            System.out.println(items.getKey());
            System.out.println(items.getValue());
        }
 myMap.forEach((k, v) ->
        {
            System.out.println(k);
            System.out.println(v);
        });
- (2)实际使用案例
 
// batchData (String -> entModel)
for (Map.Entry<String, entModel> items : batchData.entrySet()) {
            Set<String> ridSet = items.getValue().getRid();
            Set<String> siteName = items.getValue().getSiteName();
            Put put = new Put(items.getKey().getBytes());
            put.addColumn(INFO, RID, String.join(",", ridSet).getBytes());
            put.addColumn(INFO, SITE_NAME, String.join(",", siteName).getBytes());
            put.addColumn(INFO, RID_COUNT, String.valueOf(ridSet.size()).getBytes());
            put.addColumn(INFO, SITE_NAME_COUNT, String.valueOf(siteName.size()).getBytes());
            putList.add(put);
// batchData, existData都是Map对象
batchData.forEach((k, v) -> existData.merge(k, v, (o, n) -> {
                    o.addEntModel(n);
                    return o;
                }));
排序
- (1)常用的是按照值排序并且取前几个,先转为List再使用
Comparator比较器类或者stream实现 
// 使用compareTo
List<Map.Entry<String, Double>> list = new ArrayList<>(myMap.entrySet());
        System.out.println(list);  // [a=1.0, b=2.5, c=1.5]
        Collections.sort(list, new Comparator<Map.Entry<String, Double>>() {
            @Override
            public int compare(Map.Entry<String, Double> o1, Map.Entry<String, Double> o2) {
                // o1.getValue().compareTo(o2.getValue()) 返回的是-1,0,1
                return o1.getValue().compareTo(o2.getValue());  // 升序
                //return o2.getValue().compareTo(o1.getValue())  // 降序
            }
        });
        // 排序之后取前几个key
        List<String> listRank = list.stream().map(x -> x.getKey()).collect(Collectors.toList()).subList(0, 2);
*(2)使用stream.sort调用Map.Entry.comparingByValue(),limit取前2,调用java.util.Comparator倒序排列,同样按key比较有Map.Entry.comparingByKey()方法
List<String> result = myMap.entrySet().stream()
                .sorted(Map.Entry.comparingByValue())  // 升序
                // .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))  // 倒序
                .limit(2)
                .map(s -> s.getKey())
                .collect(Collectors.toList());
merge
Map合并,新则插入,有则按照指定的规则更新value,merge的三个参数分别是插入的key,value,key冲突时value,新建一个entInfo对象,在entInfo中取值作为Map
class EntInfo {
    private String name;
    private double score;
    public EntInfo(String name, double score) {
        this.name = name;
        this.score = score;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getScore() {
        return score;
    }
    public void setScore(double score) {
        this.score = score;
    }
}
- (1)多个Map合并,key冲突以新的value作为value
 
        Map<String, Double> a = new HashMap<>();
        List<EntInfo> b = new ArrayList<>();
        b.add(new EntInfo("a", 23.0));
        b.add(new EntInfo("b", 24.3));
        b.add(new EntInfo("a", 25.7));
        b.add(new EntInfo("a", 21.3));
        b.add(new EntInfo("b", 21.0));
        b.forEach(s -> a.merge(s.getName(), s.getScore(), (o, n) -> n));
- (2)多个Map合并,key冲突以大的value作为value
 
        b.forEach(s -> a.merge(s.getName(), s.getScore(), (o, n) -> o > n ? o : n));
        System.out.println(a); 
- (3)多个Map合并,key冲突对前后两个value进行处理
 
        Map<String, String> c = new HashMap<>();
        b.forEach(s -> c.merge(s.getName(), String.valueOf(s.getScore()), (o, n) -> o + "_" + n));
- (4)在merge的key冲突处理中新建和输出对象
 
        Map<String, Map> d = new HashMap<>();
        b.forEach(s -> d.merge(s.getName(), new HashMap<String, Double>() {{
            put(s.getName(), 1.0);
        }}, (o, n) -> n));
- (5)在mergekey冲突处理中加入更加复杂的代码块,使用
return得到输出 
        Map<String, Map> e = new HashMap<>();
        b.forEach(s -> e.merge(s.getName(), new HashMap<String, Double>() {{
            put(s.getName(), 1.0);
        }}, (o, n) -> {
            o.put(s.getName(), o.get("" + s.getName()) + "," + n.get(s.getName()));
            return o;
        }));
一个实际案例
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
public class entModel {
    private final Set<String> ridSet = new HashSet<>();
    private final Set<String> siteNameSet = new HashSet<>();
    public Set<String> getRid() {
        return ridSet;
    }
    public void setRid(String rid) {
        this.ridSet.add(rid);
    }
    public void setAllRid(String rids) {
        this.ridSet.addAll(Arrays.asList(rids.split(",")));
    }
    public Set<String> getSiteName() {
        return siteNameSet;
    }
    public void setSiteName(String siteName) {
        this.siteNameSet.add(siteName);
    }
    public void setAllSiteName(String siteNames) {
        this.siteNameSet.addAll(Arrays.asList(siteNames.split(",")));
    }
    public void addEntModel(entModel ent) {
        this.ridSet.addAll(ent.ridSet);
        this.siteNameSet.addAll(ent.siteNameSet);
    }
    @Override
    public String toString() {
        return "entModel{" +
                "ridSet=" + ridSet +
                ", siteNameSet=" + siteNameSet +
                '}';
    }
}
使用merge合并两个Map<String, entModel>,key冲突则调用entModel的addEntModel方法,输出新的entModel对象
batchData.forEach((k, v) -> existData.merge(k, v, (o, n) -> {
                    o.addEntModel(n);
                    return o;
                }));
取最大最小值
使用Collections.max,Collections.min工具实现取key,value的最大最小值
       Double maxValue = Collections.min(myMap.values());
        String maxKey = Collections.max(myMap.keySet());