java8 实现map以value值排序操作

网友投稿 390 2023-02-14

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 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 sortedMap = new LinkedHashMap<>();

Map sortedMap2 = new LinkedHashMap<>();

//ASC

map.entrySet().stream()

.sorted(Map.Entry.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.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 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 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 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 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生成的代理类如下所示

//

/mxkTxLjRE/ 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 类强转异常

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:Java实现简单的socket通信教程
下一篇:Java上传文件FTP服务器代码实例
相关文章

 发表评论

暂时没有评论,来抢沙发吧~