java8 实现map以value值排序操作
我就废话不多说了,大家还是直接看代码吧~
import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.stream.Collector; import java.util.stream.Collectors; import java.util.LinkedHashMap; public class MapSorted{ public static void main(String[] args) { Map<String, Integer> map = new HashMap<>(); map.put("A", 3); map.put("B", 5); map.put("C", 1); map.put("D", 1); map.put("E", 9); System.out.println(map); //如果value为java对象,则需要实现Comparable接口,重写compareTo方法 Map<String, Integer> sortedMap = new LinkedHashMap<>(); Map<String, Integer> sortedMap2 = new LinkedHashMap<>(); //ASC map.entrySet().stream() .sorted(Map.Entry.<String, Integer>comparingByValue()) .forEachOrdered(x -> sortedMap.put(x.getKey(), x.getValue())); System.out.println(sortedMap); //DESC Collections.reverseOrder || reversed() map.entrySet().stream() .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) .forEachOrdered(x -> sortedMap2.put(x.getKey(), x.getValue())); // map.entrySet().stream() // .sorted(Map.Entry.<String, Integer>comparingByValue().reversed()) // .forEachOrdered(x -> sortedMap2.put(x.getKey(), x.getValue())); System.out.println(sortedMap2); //Collectors.toMap 直接返回排好序的map map = map.entrySet().stream() .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) .collect(Collectors.toMap(x -> x.getKey(), x -> x.getValue(), (x1, x2) -> x2, LinkedHashMap::new)); // map = map.entrySet().stream() // .sorted(Collections.reverseOrder(Map.Entry.comparingByValue())) // .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (x1, x2) -> x2, LinkedHashMap::new)); System.out.println(map); } }
{A=3, B=5, C=1, D=1, E=9} {C=1, D=1, A=3, B=5, E=9} {E=9, B=5, A=3, C=1, D=1} {E=9, B=5, A=3, C=1, D=1}
补充知识:对BeanCopier拷贝对象中List类型属性的思考
背景
最近开发接口过程中,使用BeanCopier拷贝对象,当对象中嵌套自定义对象类型属性的时候,
如果对象名称一致,但是对象类型不一致,拷贝的时候,该属性是会被忽略的,但是当对象中嵌套List集合类型属性(集合中是不同的对象类型)时,使用BeanCopier拷贝之后,返回给前台的数据是正确的,感觉不太懂其中的原理,就测试了下。
测试过程
新建几个对象
@Data @NoArgsConstructor @AllArgsConstructor public class ClassA { private String id; private String name; } @Data @NoArgsConstructor @AllArgsConstructor public class ClassB { private String id; private String name; } @Data @NoArgsConstructor @AllArgsConstructor public class BeanA { private String name; private List<ClassA> aList; }F @Data @NoArgsConstructor @AllArgsConstructor public class BeanA1 { private String name; private ClassA className; } @Data @NoArgsConstructor @AllArgsConstructor public class BeanB { private String name; private List<ClassB> aList; } Data @NoArgsConstructor @AllArgsConstructor public class BeanB1 { private String name; private ClassB className; }
拷贝BeanA1到BeanB1
public static void main(String[] args) { /** * 将cglib生成的代理类的class文件打印到指定目录 */ System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "/Users/haiyoung/logs"); BeanA1 beanA1 = new BeanA1(); beanA1.setName("aaa"); beanA1.setClassName(new ClassA("001", "001")); BeanB1 beanB1 = new BeanB1(); BeanCopier beanCopier = BeanCopier.create(BeanA1.class, BeanB1.class,false); beanCopier.copy(beanA1, beanB1,null); System.out.println(beanB1); }
转换结果如下图所示:对象类型被忽略
cglib生成的代理类如下所示
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package org.springframework.cglib.empty; import com.haiyoung.hyweb.beanCopier.BeanA1; import com.haiyoung.hyweb.beanCopier.BeanB1; import org.springframework.cglib.beans.BeanCopier; import org.springframework.cglib.core.Converter; public class Object$$BeanCopierByCGLIB$$c00337e1 extends BeanCopier { public Object$$BeanCopierByCGLIB$$c00337e1() { } public void copy(Object var1, Object var2, Converter var3) { ((BeanB1)var2).setName(((BeanA1)var1).getName()); } }
从copy实现代码中可以看到,不同对象类型属性间的拷贝被忽略
拷贝BeanA到BeanB
public static void main(String[] args) { /** * 将cglib生成的代理类的class文件打印到指定目录 */ System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, "/Users/haiyoung/logs"); BeanA beanA = new BeanA(); beanA.setName("aaa"); List<ClassA> list = new ArrayList<>(); list.add(new ClassA("001", "001")); beanA.setAList(list); BeanB beanB = new BeanB(); BeanCopier beanCopier = BeanCopier.create(BeanA.class, BeanB.class,false); beanCopier.copy(beanA, beanB,null); System.out.println(beanB); List<ClassB> list1 = beanB.getAList(); System.out.println(list1); // ClassB classB = list1.get(0); // // System.out.println(classB); }
转换结果如下图所示,list对象类型属性被成功赋值
但是对象beanA和benaB中的List属性,指向相同的引用,当用ClassB接收beanB中的List属性中的对象时,
会报对象强转失败
Exception in thread "main" [ClassA(id=001, name=001)] java.lang.ClassCastException: com.haiyoung.hyweb.beanCopier.ClassA cannot be cast to com.haiyoung.hyweb.beanCopier.ClassB at com.haiyoung.hyweb.beanCopier.CopyTest.main(CopyTest.java:44)
cglib生成的代理类如下所示
// // Source code recreated from a .class file by IntelliJ IDEA // (powered by Fernflower decompiler) // package org.springframework.cglib.empty; import com.haiyoung.hyweb.beanCopier.BeanA; import com.haiyoung.hyweb.beanCopier.BeanB; import org.springframework.cglib.beans.BeanCopier; import org.springframework.cglib.core.Converter; public class Object$$BeanCopierByCGLIB$$27129331 extends BeanCopier { public Object$$BeanCopierByCGLIB$$27129331() { } public void copy(Object var1, Object var2, Converter var3) { BeanB var10000 = (BeanB)var2; BeanA var10001 = (BeanA)var1; var10000.setAList(((BeanA)var1).getAList()); var10000.setName(var10001.getName()); } }
从copy的实现代码中可以看到,两个对象中的List类型的对象集合属性被成功赋值,但是是引用赋值
结论
BeanCopier对不同对象中的List对象集合类型的属性的拷贝是弱拷贝,而不是深拷贝,如果只是做对象拷贝,然后直接抛出这个对象给前台使用是没有问题的,但是如果这个通过拷贝得到的对象要在代码中进行业务流转,则会报java.lang.ClassCastException 类强转异常
以上这篇java8 实现map以value值排序操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。
赞 (0)