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)

相关推荐

  • Java8 Map中新增的方法使用总结

    前言 得益于 Java 8 的 default 方法特性,Java 8 对 Map 增加了不少实用的默认方法,像 getOrDefault, forEach, replace, replaceAll, putIfAbsent, remove(key, value), computeIfPresent, computeIfAbsent, compute 和merge 方法.另外与 Map 相关的 Map.Entry 也新加了多个版本的 comparingByKey 和 comparingByVal

  • Java Map 按照Value排序的实现方法

    Map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,Hashtable以及LinkedHashMap等. •TreeMap:基于红黑树(Red-Black tree)的 NavigableMap 实现,该映射根据其键的自然顺序进行排序,或者根据创建映射时提供的 Comparator 进行排序,具体取决于使用的构造方法. •HashMap的值是没有顺序的,它是按照key的HashCode来实现的,对于这个无序的HashMap我们要怎么来实现排序呢?参照TreeMap的va

  • JAVA8独有的map遍历方式(非常好用)

    使用JAV8 带来的map遍历方式使遍历非常简单 public class LambdaMap { private Map<String, Object> map = new HashMap<>(); @Before public void initData() { map.put("key1", "value1"); map.put("key2", "value2"); map.put("k

  • java8 stream 操作map根据key或者value排序的实现

    引言 最近小编自己一个人在负责一个项目的后台开发,其中有一部分是统计相关的功能,所以需要一些排序或者分组的操作,之前这种操作小编觉得还是比较麻烦的,虽热有一些现成的工具类,但是工具类的写法也是比较复杂的,但是如果使用java8 stream流的话就比较简单了,并且代码量会大大的减少,下面总结几个对map的操作. 1.map 根据value排序 Map<String,BigDecimal> map =new HashMap<>(); map.put("one",

  • 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(

  • 如何利用Java8 Stream API对Map按键或值排序

    一.什么是Java 8 Stream 使用Java 8 Streams,我们可以按键和按值对映射进行排序.下面是它的工作原理: Java Stream函数式编程?用过都说好,案例图文详解送给你 将Map或List等集合类对象转换为Stream对象 使用Streams的sorted()方法对其进行排序 最终将其返回为LinkedHashMap(可以保留排序顺序) sorted()方法以Comparator作为参数,从而可以按任何类型的值对Map进行排序.如果对Comparator不熟悉,可以看本号

  • java8中Map的一些骚操作总结

    一 前言 本篇内容是关于 map 新特性的一些方法使用上的介绍,如果有不足之处欢迎补充!! 二 map新特性 关于以下函数式编程的函数的计算知识追寻者都使用 简单字符串代替了,参数无非就是Key,value: 2.1 forEach forEach迭代,相当于for循环 public static void main(String[] args) { HashMap<String, Object> hashMap = new HashMap<>(); hashMap.put(&qu

  • golang 实现对Map进行键值自定义排序

    看代码吧~ //自定义结构体,用来自定义排序 type RecentlyUpdateListMapSorter []map[string]interface{} //根据MapSorter.Keys进行倒序排序 func (ms *RecentlyUpdateListMapSorter) SortReverse() { sort.Sort(sort.Reverse(ms)) } //自定义排序方法(Len(),Less(),Swap()) func (ms *RecentlyUpdateList

  • 浅谈Java之Map 按值排序 (Map sort by value)

    Map是键值对的集合,又叫作字典或关联数组等,是最常见的数据结构之一.在java如何让一个map按value排序呢? 看似简单,但却不容易! 比如,Map中key是String类型,表示一个单词,而value是int型,表示该单词出现的次数,现在我们想要按照单词出现的次数来排序: Map map = new TreeMap(); map.put("me", 1000); map.put("and", 4000); map.put("you", 3

  • Python实现的字典排序操作示例【按键名key与键值value排序】

    本文实例讲述了Python实现的字典排序操作.分享给大家供大家参考,具体如下: 对字典进行排序?这其实是一个伪命题,搞清楚python字典的定义---字典本身默认以key的字符顺序输出显示---就像我们用的真实的字典一样,按照abcd字母的顺序排列,并且本质上各自没有先后关系,是一个哈希表的结构: 但实际应用中我们确实有这种排序的"需求"-----按照values的值"排序"输出,或者按照别的奇怪的顺序进行输出,我们只需要把字典转化成list或者tuple,把字典每

  • java实现对map的字典序排序操作示例

    本文实例讲述了java实现对map的字典序排序操作.分享给大家供大家参考,具体如下: java中对map的字典序排序,算法验证比对微信官网https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141115&token=&lang=zh_CN,搜索关键字"附录1-JS-SDK使用权限签名算法" import java.util.ArrayList; import java.util.Collectio

  • Java中对list map根据map某个key值进行排序的方法

    实例如下所示: package test; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.List; import java.util.Map; public class java_ListMapSort { public static void main(String[] args)

  • 浅析Java8 中 Map 接口的新方法

    我们提一个需求:给定一个 List<String> ,统计每个元素出现的所有位置. 比如,给定 list: ["a", "b", "b", "c", "c", "c", "d", "d", "d", "f", "f", "g"] ,那么应该返回: a : [

  • Java实现对两个List快速去重并排序操作示例

    本文实例讲述了Java实现对两个List快速去重并排序操作.分享给大家供大家参考,具体如下: 1:去重并排序 package twolist; import java.util.Collections; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.uti

随机推荐