Comaparator接口用于实现排序,通常作为排序的参数输入,如Collections.sort(array,Comparator),接口中包含compare(Object obj1,Object obj2)和equals(Object obj)方法,compare方法用于比较obj1和obj2,obj1>obj2,return 大于0的数,相等return0,小于则return小于零的数
接口实现方法:类实现(重写compare方法,equals方法Object类中实现,因此不需要重写)、lambda表达式
public void test5() {
//TreeMap的定制排序
Comparator com = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Person1 && o2 instanceof Person1) {
Person1 p1 = (Person1) o1;
Person1 p2 = (Person1) o2;
int i = p1.getSex().compareTo(p2.getSex());
if (i == 0) {
return p1.getAge().compareTo(p2.getAge());
}
return i;
}
return 0;
}
};
Map map = new TreeMap(com);
map.put(new Person1("AA", 23), 55);
map.put(new Person1("CC", 44), 55);
map.put(new Person1("ZZ", 255), 55);
map.put(new Person1("DD", 32), 55);
map.put(new Person1("GG", 11), 55);
map.put(new Person1("MM", 15), 55);
map.put(new Person1("CC", 33), 55);
for (Object a : map.keySet()) {
System.out.println(a + "=" + map.get(a));
}
}
Lambda表达式允许通过表达式来代替功能接口功能(注意表达式中参数以及参数方法的一致性,使用中尽量添加泛型约束)
通过另一篇博客进行学习,本文中进行了一些转载和自己的相关测试:Lambda表达式的使用
// 1. 不需要参数,返回值为 5
() -> 5
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)
String[] arr=new String[]{
"sdf","dsf","34"};
List<String> list= Arrays.asList(arr);
//1、以往for循环
for(String a:list){
System.out.print(a+" ");
}
System.out.println();
//2、forEach和Lambda
//forEach()即增强for循环方法,测试发现引用数据类型Integer和String等没有这个方法
list.forEach((a)-> System.out.print(a+" "));
//1、匿名内部类
Person p1=new Person(){
@Override
public void run() {
System.out.println("hello");
}
};
//2、Lambda
Person p2=()-> System.out.println("hello");
p1.run();
p2.run();
Comparator com = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Person1 && o2 instanceof Person1) {
Person1 p1 = (Person1) o1;
Person1 p2 = (Person1) o2;
int i = p1.getSex().compareTo(p2.getSex());
if (i == 0) {
return p1.getAge().compareTo(p2.getAge());
}
return i;
}
return 0;
}
};
Map map = new TreeMap(com);
(2)Lambda表达式实现Comparator接口
Comparator<Person1> com1=(p1,p2)->p1.getAge().compareTo(p2.getAge());
Map map=new TreeMap(com1);
**注意:**在网上找了一些学习资料后,自己测试过程中遇到了Comparator com1=(p1,p2)->p1.getAge().compareTo(p2.getAge());这行代码报错的问题,刚开始以为是Person1类中我没有实现compareTo方法,但是修改后还是不对,多次测试后发现,Comparator中,T默认为Object类,因此只要输入参数p1和p2不是此类就会报错,而且Lambda表达式中会自动识别输入参数类,不需要用类来修饰。
(3)匿名Lambda表达式
TreeMap构造器中传入匿名Lambda表达式时需要加泛型,在使用匿名Lambda方法时需要注意
Map map=new TreeMap<>((Person1 p1,Person1 p2)->p1.getAge().compareTo(p2.getAge()));
//源码:
public PriorityQueue(Comparator<? super E> comparator) {
this(DEFAULT_INITIAL_CAPACITY, comparator);
}
//测试:
PriorityQueue heap=new PriorityQueue<Integer>((n1,n2)->n1-n2);
//add()、offer():向优先队列中添加元素,插入失败add()抛出异常,offer()返回false
heap.offer(20);
heap.offer(1);
heap.offer(58);
System.out.println(heap);
可以看到,每添加一个元素,优先队列就按照排序方法排序为小顶堆
//element()、peek():都是获取但不删除队首元素,方法失败时前者抛出异常,后者返回null
System.out.println(heap.peek());
PriorityQueue heap=new PriorityQueue<Integer>((n1,n2)->n1-n2);
heap.offer(20);
heap.offer(15);
heap.offer(58);
heap.offer(17);
System.out.println(heap);
//remove()、poll():获取并删除队首元素,当方法失败时前者抛出异常,后者返回null
//按照小顶堆二叉树原理,将根节点元素和最后一个叶节点元素调换,并删去此叶节点,之后对二叉树重新小顶堆
heap.poll();
System.out.println(heap);