Comparator
概念
- 自1.8以后,Compartor成为一个函数式接口,该接口用于返回一个比较器,比较器主要用于排序
- 将容器中的数据进行比较,若是两个数据相等则返回0 ,前者大于后者返回1,前者小于后者返回-1,默认情况下会根据升序进行排序
用法
1.配合各类容器(如流、集合、数组)进行排序
方法代码示例
方法名 | 代码示例 | 解释说明 |
---|---|---|
compare | (e1,e2)->{return e1>e2? 1:(e1==e2?0:-1)} | 是函数式接口的唯一抽象方法,可以使用Lambda重写后返回一个比较器。直接使用的话不好用,不推荐使用 |
comparing(Function<? super T,? extends U> keyExtractor) | Compare.comparing(String::length) 以字符串长度作为比较的标准 | 是一个静态方法,用自定义Lambda表达式确定比较规则,而后返回一个比较器 |
comparing(Function<? super T,? extends U> keyExtractor, Comparator<? super U> keyComparator) | Comparator.comparing (String::length,Comparator.reverseOrder()) 先把字符串长度提取出来而后根据长度进行翻转排序 | 是一个静态方法,首先将元素提取出来,而后对提取出来的元素进行比较排序 |
comparingDouble(ToDoubleFunction keyExtractor) | 参考comparing,这个只是指定了 一个double类型的函数返回值 | 参考comparing |
comparingInt(ToIntFunction<? super T> keyExtractor) | 参考comparing,这个只是指定了 一个int类型的函数返回值 | 参考comparing |
comparingLong(ToLongFunction<? super T> keyExtractor) | 参考comparing,这个只是指定了 一个long类型的函数返回值 | 参考comparing |
equals() | 同Object.euqals()方法 | 继承自Object类的方法,官方建议不要重写,如果重写一样要申明于API中 |
naturalOrder() | Comparator.naturalOrder | 这是一个静态方法,可以返回自然顺序的排序器 |
nullsFirst(Comparator<? super T> comparator) | Comparator.nullsFirst (Comparator.comparing(String::length)) | 静态方法,对空元素友好的比较器,会将空元素当成最小元素 |
nullsLast(Comparator<? super T> comparator) | Comparator.nullsLast (Comparator.comparing(String::length)) | 静态方法,对空元素友好的比较器,会将空元素当成最大元素 |
reversed() | Comparator.comparing(String::length).reversed() | 实例方法,翻转原来的排序方案 |
reverseOrder() | Comparator.reverseOrder(); | 静态方法,返回一个翻转比较器。 |
thenComparing(Comparator<? super T> other) | Comparator.comparing(String::length). thenComparing (String.CASE_INSENSITIVE_ORDER); | 默认方法,紧跟在比较器之后再比较,二次排序 |
thenComparing(Function<? super T,? extends U> keyExtractor) | 参考上述用法 | 参考上述用法 |
thenComparing(Function<? super T,? extends U> keyExtractor, Comparator<? super U> keyComparator) | 参考上述用法 | 参考上述用法 |
thenComparingDouble(ToDoubleFunction<? super T> keyExtractor) | 参考上述用法 | 参考上述用法 |
thenComparingInt(ToIntFunction<? super T> keyExtractor) | 参考上述用法 | 参考上述用法 |
thenComparingLong(ToLongFunction<? super T> keyExtractor) | 参考上述用法 | 参考上述用法 |
注意事项
好像暂时没有踩到什么坑,欢迎各位帮忙补充。
小练习
-
生成一个商品笔类,属性有商品名称,商品批次,进货人,进货时间,进货量,进货价格,运输时间。而后创建6个实例,要求生成的实例信息见表格(全部信息以字符串形式存储)
商品名称 商品批次 进货人 进货时间 进货量(pcs) 进货单价(¥) 运输时间(小时) 铅笔 A01 张三 2020/1/2 100 1 100 铅笔 B01 李四 2020/2/1 200 1.5 50 铅笔 A11 王五 2020/11/1 300 1 120 钢笔 A02 赵六 2020/1/4 160 2 150 圆珠笔 A02 张三 2020/12/1 3000 3 200 油性笔 A02 钱一 2020/5/20 1 5 10 ①:请根据商品名称的拼音进行降序排序,而后在此基础上,根据进货单价进行升序排序
②:请根据商品名称的拼音进行降序排序,而后在此基础上,根据商品批次进行升序排序
③:在①的基础上,根据进货时间降序排序
④:我真的编不出来了,你们自己看着表格改改数据瞎编点把哈哈
下面有答案,看看你有没有更方便的方法
import java.io.IOException;
import java.text.Collator;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
class OnSalePen {
private String name;
private String productBatch;
private String buyer;
private String buyTime;
private String amount;
private String singlePrice;
private String transportTime;
public OnSalePen(String name, String productBatch, String buyer, String buyTime, String amount, String singlePrice,
String transportTime) {
super();
this.name = name;
this.productBatch = productBatch;
this.buyer = buyer;
this.buyTime = buyTime;
this.amount = amount;
this.singlePrice = singlePrice;
this.transportTime = transportTime;
}
public OnSalePen() {
super();
// TODO Auto-generated constructor stub
}
@Override
public String toString() {
return "OnSalePen [name=" + name + ", productBatch=" + productBatch + ", buyer=" + buyer + ", buyTime="
+ buyTime + ", amount=" + amount + ", singlePrice=" + singlePrice + ", transportTime=" + transportTime
+ "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getProductBatch() {
return productBatch;
}
public void setProductBatch(String productBatch) {
this.productBatch = productBatch;
}
public String getBuyer() {
return buyer;
}
public void setBuyer(String buyer) {
this.buyer = buyer;
}
public String getBuyTime() {
return buyTime;
}
public void setBuyTime(String buyTime) {
this.buyTime = buyTime;
}
public String getAmount() {
return amount;
}
public void setAmount(String amount) {
this.amount = amount;
}
public String getSinglePrice() {
return singlePrice;
}
public void setSinglePrice(String singlePrice) {
this.singlePrice = singlePrice;
}
public String getTransportTime() {
return transportTime;
}
public void setTransportTime(String transportTime) {
this.transportTime = transportTime;
}
}
public class CollectionMethodTest {
public static void main(String[] args) throws IOException {
OnSalePen p1 = new OnSalePen("铅笔", "A01", "张三", "2020/1/2", "100", "1", "100");
OnSalePen p2 = new OnSalePen("铅笔", "B01", "李四", "2020/2/1", "200", "1.5", "50");
OnSalePen p3 = new OnSalePen("铅笔", "A11", "王五", "2020/11/1", "300", "1", "120");
OnSalePen p4 = new OnSalePen("钢笔", "A02", "赵六", "2020/1/4", "160", "2", "150");
OnSalePen p5 = new OnSalePen("圆珠笔", "A02", "张三", "2020/12/1", "3000", "3", "200");
OnSalePen p6 = new OnSalePen("油性笔", "A02", "钱一", "2020/5/20", "1", "5", "10");
List<OnSalePen> penList = new ArrayList<OnSalePen>();
penList.add(p1);
penList.add(p2);
penList.add(p3);
penList.add(p4);
penList.add(p5);
penList.add(p6);
// 请根据商品名称的拼音进行降序排序,而后在此基础上,根据进货单价进行升序排序
Comparator<OnSalePen> c1 = Comparator
.comparing(OnSalePen::getName, Collator.getInstance(java.util.Locale.CHINA)).reversed();// 先对商品名称的拼音进行排序
Comparator<OnSalePen> c01 = c1.thenComparing(OnSalePen::getSinglePrice);// 在c1的基础上再对进货单价进行排序
// 请根据商品名称的拼音进行降序排序,而后在此基础上,根据商品批次进行升序排序
Comparator<OnSalePen> c02 = c1.thenComparing(OnSalePen::getProductBatch);// 在c1的基础上再对进货批次进行排序
// 在①的基础上,根据进货时间降序排序
Comparator<OnSalePen> c03 = c01.thenComparing(ele -> {
String s = ele.getBuyTime();
String[] split = s.split("/");
split[1] = split[1].length() == 2 ? split[1] : "0" + split[1];//此处防止信息输入的有问题,保证一定输出两位长度的字符串
split[2] = split[2].length() == 2 ? split[2] : "0" + split[2];//此处防止信息输入的有问题,保证一定输出两位长度的字符串
String s1 = split[0] + "-"+split[1] + "-" +split[2];//重新拼接字符串
LocalDate parse = LocalDate.parse(s1);
return parse;
},Comparator.reverseOrder());
penList.stream().sorted(c01).forEach(System.out::println);// 请根据商品名称的拼音进行降序排序,而后在此基础上,根据进货单价进行升序排序
System.out.println("===============================================================================================================");
penList.stream().sorted(c02).forEach(System.out::println);// 请根据商品名称的拼音进行降序排序,而后在此基础上,根据商品批次进行升序排序
System.out.println("===============================================================================================================");
penList.stream().sorted(c03).forEach(System.out::println);// 在①的基础上,根据进货时间降序排序
}
}