根据对象字段的分组对列表进行排序,根据组中的最大值进行排序
Sort a list based on grouping on object fields, sort based on maximum in the group
我正在尝试根据分组对数组列表进行排序。
假设我有一份货币和现金清单
100 美元,
75 加元,
10 美元,
80 欧元,
5 美元
我想根据货币降序的最大现金对列表进行排序,因此所需的输出应该是这样的。
100 美元、10 美元、5 美元、80 欧元、75 加元。
我在下面写了 类 来实现相同但没有运气,有人可以帮忙吗。
import java.math.BigDecimal;
import java.util.Comparator;
public class BO {
String ccy;
BigDecimal cash;
public String getCcy() {
return ccy;
}
public void setCcy(String ccy) {
this.ccy = ccy;
}
public BigDecimal getCash() {
return cash;
}
public void setCash(BigDecimal cash) {
this.cash = cash;
}
@Override
public String toString() {
return "BO [ccy=" + ccy + ", cash=" + cash + "]";
}
public static final Comparator<BO> CUSTOM_SORTER = new Comparator<BO>() {
@Override
public int compare(BO o1, BO o2) {
return o2.getCash().compareTo(o1.getCash());
}
};
}
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class BODriver {
public static void main(String[] args) {
BO one = new BO();
one.setCcy("USD");
one.setCash(new BigDecimal(100));
BO two = new BO();
two.setCcy("CAD");
two.setCash(new BigDecimal(50));
BO three = new BO();
three.setCcy("USD");
three.setCash(new BigDecimal(10));
BO four = new BO();
four.setCcy("EUR");
four.setCash(new BigDecimal(70));
BO five = new BO();
five.setCcy("USD");
five.setCash(new BigDecimal(5));
List<BO> boList = new ArrayList<BO>();
boList.add(five);
boList.add(four);
boList.add(three);
boList.add(two);
boList.add(one);
System.out.println("Before sort");
System.out.println(boList);
Collections.sort(boList,BO.CUSTOM);
System.out.println("After sort");
System.out.println(boList);
}
}
也许您可以将字符串字段添加到 BO class 以连接 ccy+" "+cash.e.g,然后您可以使用该字符串字段轻松对对象进行排序。
public static final Comparator<BO> CUSTOM_SORTER = new Comparator<BO>() {
@Override
public int compare(BO o1, BO o2) {
if(o2.getCcy().compareTo(o1.getCcy())==0)
return o2.getCash().compareTo(o1.getCash());
else
return o2.getCcy().compareTo(o1.getCcy());
}
};
试试这个作为你的比较器..
这里有两个步骤。
首先找到每种货币的最大值:
Map<String, BigDecimal> maxGroup = boList.stream().collect(
Collectors.toMap(BO::getCcy, BO::getCash, BigDecimal::max) );
然后首先按最大现金价值排序,然后按货币排序,最后按每个 BO
对象中的现金价值排序:
Comparator<BO> comparator = Comparator
.<BO, BigDecimal>comparing( (bo) -> maxGroup.get( bo.getCcy() ) ).reversed() //first compare by max cash in desc order
.thenComparing(BO::getCcy) //then by currency
.thenComparing( Comparator.comparing(BO::getCash).reversed() ); //and finally by cash in desc order
Collections.sort( boList, comparator);
我正在尝试根据分组对数组列表进行排序。 假设我有一份货币和现金清单 100 美元, 75 加元, 10 美元, 80 欧元, 5 美元
我想根据货币降序的最大现金对列表进行排序,因此所需的输出应该是这样的。 100 美元、10 美元、5 美元、80 欧元、75 加元。
我在下面写了 类 来实现相同但没有运气,有人可以帮忙吗。
import java.math.BigDecimal;
import java.util.Comparator;
public class BO {
String ccy;
BigDecimal cash;
public String getCcy() {
return ccy;
}
public void setCcy(String ccy) {
this.ccy = ccy;
}
public BigDecimal getCash() {
return cash;
}
public void setCash(BigDecimal cash) {
this.cash = cash;
}
@Override
public String toString() {
return "BO [ccy=" + ccy + ", cash=" + cash + "]";
}
public static final Comparator<BO> CUSTOM_SORTER = new Comparator<BO>() {
@Override
public int compare(BO o1, BO o2) {
return o2.getCash().compareTo(o1.getCash());
}
};
}
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class BODriver {
public static void main(String[] args) {
BO one = new BO();
one.setCcy("USD");
one.setCash(new BigDecimal(100));
BO two = new BO();
two.setCcy("CAD");
two.setCash(new BigDecimal(50));
BO three = new BO();
three.setCcy("USD");
three.setCash(new BigDecimal(10));
BO four = new BO();
four.setCcy("EUR");
four.setCash(new BigDecimal(70));
BO five = new BO();
five.setCcy("USD");
five.setCash(new BigDecimal(5));
List<BO> boList = new ArrayList<BO>();
boList.add(five);
boList.add(four);
boList.add(three);
boList.add(two);
boList.add(one);
System.out.println("Before sort");
System.out.println(boList);
Collections.sort(boList,BO.CUSTOM);
System.out.println("After sort");
System.out.println(boList);
}
}
也许您可以将字符串字段添加到 BO class 以连接 ccy+" "+cash.e.g,然后您可以使用该字符串字段轻松对对象进行排序。
public static final Comparator<BO> CUSTOM_SORTER = new Comparator<BO>() {
@Override
public int compare(BO o1, BO o2) {
if(o2.getCcy().compareTo(o1.getCcy())==0)
return o2.getCash().compareTo(o1.getCash());
else
return o2.getCcy().compareTo(o1.getCcy());
}
};
试试这个作为你的比较器..
这里有两个步骤。
首先找到每种货币的最大值:
Map<String, BigDecimal> maxGroup = boList.stream().collect(
Collectors.toMap(BO::getCcy, BO::getCash, BigDecimal::max) );
然后首先按最大现金价值排序,然后按货币排序,最后按每个 BO
对象中的现金价值排序:
Comparator<BO> comparator = Comparator
.<BO, BigDecimal>comparing( (bo) -> maxGroup.get( bo.getCcy() ) ).reversed() //first compare by max cash in desc order
.thenComparing(BO::getCcy) //then by currency
.thenComparing( Comparator.comparing(BO::getCash).reversed() ); //and finally by cash in desc order
Collections.sort( boList, comparator);