java8 stream sort自定义复杂排序案例

网友投稿 590 2022-11-18


java8 stream sort自定义复杂排序案例

java 8 自定义排序

需求

今天在项目中遇到个需求,按照对象中的三个属性进行排序。

具体要求:

前提:对象 Obj [a=a,b=b,c=c]

1、 优先级为a > b > c

2、 a属性为中文,固定排序规则为:政府,合作,基金 … …

3、 b的为BigDecimal类型,固定的排序规则为:降序排序

4、 c为java.util.Date类型,规则为:降序排序

其实看这个需求,第3点和第4点不是什么问题,但是第1点,会考虑下怎么实现好。

直接上方案吧!

方案一

新建一张排序表,至少要有字段 【名称—中文名称(政府、合作、基金等)】【排序编号—(1、2、3)】,在Obj表中的a字段存排序表的id。

此时可以直接用sql语句 ORDER BY 排序即可。

优点:可动态配置。

方案二

完全用java代码操作,和sql无关,上代码:

Obj.java 和 Sort.java

package TestSort;

import java.math.BigDecimal;

public class Obj {

private String name;

private BigDecimal price;

public Obj(String name, BigDecimal price){

this.name = name;

this.price = price;

}

public Obj(){

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public BigDecimal getPrice() {

return price;

}

public void setPrice(BigDecimal price) {

this.price = price;

}

@Ohttp://verride

public String toString() {

return "Obj [name=" + name + ", price=" + price + "]";

}

}

package TestSort;

import java.math.BigDecimal;

import java.util.Arrays;

import java.util.Comparator;

import java.util.List;

import java.util.stream.Collectors;

public class Sort {

public static void main(String[] args) {

List list = Arrays.asList(

new Obj("政府", null),

new Obj("政府", new BigDecimal("1216.23")),

new Obj("商业", new BigDecimal("123.23")),

new Obj("PPD", new BigDecimal("123.23")),

new Obj("合作", new BigDecimal("127.23")),

new Obj("合作", new BigDecimal("125.23")),

new Obj("咨询", null),

new Obj(null, null)

);

/*Comparator byName = Comparator.comparing(Obj::getName).reversed();

Comparator finalByPrice= byName.thenComparing(Obj::getPrice,Comparator.nullsFirst(BigDecimal::compareTo)).reversed();

List result = list.stream().filter(new Predicate() {

@Override

public boolean test(Obj obj) {

if(obj.getName() == null && obj.getPrice() ==null){

return false;

}

return true;

}

}).sorted(finalByPrice).collect(Collectors.toList());*/

List result = list.stream().sorted(

//先按照name排序(模拟需求的a属性排序)

Comparator.comparing(Obj::getName,(x,y)->{

if(x == null && y != null){

return 1;

}else if(x !=null && y == null){

return -1;

}else if(x == null && y == null){

return -1;

}else if("PPD".equals(x) || "PPD".equals(y)){

if(x.equals(y)){

return 0;

}else if("PPD".equals(x)){

return -1;

}else{

return 1;

}

}else

if("合作".equals(x) || "合作".equals(y)){

if(x.equals(y)){

return 0;

}else if("合作".equals(x)){

return -1;

}else{

return 1;

}

}else

if("政府".equals(x) || "政府".equals(y)){

if(x.equals(y)){

return 0;

}else if("政府".equals(x)){

return -1;

}else{

return 1;

}

}

return 0; })

//再按照其他字段排序,要考虑null(模拟需求b和c字段排序)

.thenComparing(Comparator.comparing(Obj::getPrice,

Comparator.nullsFirst(BigDecimal::compareTo)).reversed()

)).collect(Collectors.toList());

System.out.println(result);

System.out.println(result.siXtkMQcqgKze());

}

}

方案二的缺点就是硬编码,用户改排序就得改源码。对第二种方案的改进:

package TestSort;

import java.math.BigDecimal;

importhttp:// java.util.Arrays;

import java.util.Comparator;

import java.util.List;

import java.util.stream.Collectors;

public class Sort {

public static void main(String[] args) {

List list = Arrays.asList(

new Obj("政府", null),

new Obj("政府", new BigDecimal("1216.23")),

new Obj("商业", new BigDecimal("123.23")),

new Obj("PPD", new BigDecimal("123.23")),

new Obj("合作", new BigDecimal("127.23")),

new Obj("合作", new BigDecimal("125.23")),

new Obj("咨询", null),

new Obj(null, null)

);

/*Comparator byName = Comparator.comparing(Obj::getName).reversed();

Comparator finalByPrice= byName.thenComparing(Obj::getPrice,Comparator.nullsFirst(BigDecimal::compareTo)).reversed();

List result = list.stream().filter(new Predicate() {

@Override

public boolean test(Obj obj) {

if(obj.getName() == null && obj.getPrice() ==null){

return false;

}

return true;

}

}).sorted(finalByPrice).collect(Collectors.toList());*/

//此处模拟从数据读取配置到list

List sortList = Arrays.asList("PPD","政府","合作");

list.stream().sorted(

Comparator.comparing(Obj::getName,(x,y)->{

if(x == null && y != null){

return 1;

}else if(x !=null && y == null){

return -1;

}else if(x == null && y == null){

return -1;

}else{

//按照读取的list顺序排序

for(String sort : sortList){

if(sort.equals(x) || sort.equals(y)){

if(x.equals(y)){

return 0;

}else if(sort.equals(x)){

return -1;

}else{

return 1;

}

}

}

return 0;

}

}).thenComparing(Comparator.comparing(Obj::getPrice,Comparator.nullsFirst(BigDecimal::compareTo)).reversed())

).collect(Collectors.toList()).forEach(System.out::println);;

}

}

补充知识:java8 stream代替for循环 sort多字段排序 group by多级排序

我就废话不多说了,大家还是直接看代码吧`

List list = new ArrayList();

Category ctg= new Category();

ctg.setType(1);//0商品,1销售规格

ctg.setSort(2);

ctg.setInheritFlag(0);//0继承属性1非继承属性

ctg.setValueSort(1)

Category ctg1= new Category();

ctg1.setType(0);//0商品,1销售规格

ctg1.setSort(1);

ctg1.setInheritFlag(1);//0继承属性1非继承属性

ctg1.setValueSort(2)

list.add(ctg);

list.add(ctg1);

lista.stream().sorted(Comparator.comparing(Category::getSort()).thenComparing(Category::getValueSort())).collect(Collectors.groupingBy(fetchGroupInheritKey(mtg)),Collectors.groupingBy(fetchGroupTypeKey(mtg)));

private String fetchGroupInheritKey(Category ctg){

if(inheritFlag==0){

return "inheritList";

}else if(inheritFlag==1){

return "ownList";

}else{

return "";

}

}

使用Comparator实现多字段排序和多级分组,前面的sort排序会影响后面的groupBy分组后的list中的排序

mcvo中有有多个property List ,按商品属性和销售属性区分将多个小list聚合为一个list

mc V o list.stream(). flat Map(mc vo→mcvo.getPropertyList(). stream ())


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

上一篇:Java获取线程ID的实例
下一篇:idea创建springboot项目和springcloud项目的详细教程
相关文章

 发表评论

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