一点一点看JDK源码(五)java.util.ArrayList 后篇之sort与Comparator
liuyuhang原创,未经允许禁止转载
本文举例使用的是JDK8的API
目录:一点一点看JDK源码(〇)
Comparator为额外实现的比较接口,与类本身无关
该接口在ArrayList的sort中有应用(很多时候都可以用的,只是以此举例)
Comparator接口主要用途有两种,
1、比较有序集合内任意两个元素A、B(完全遍历的compareTo方法,于compare方法内实现)
若A元素小于B元素,则返回1,donothing
若A元素等于B元素,则返回0,donothing
若A元素小于B元素,则返回-1,交换元素位置
若compare方法的返回值遵循以上原则,则进行排序
示例代码如下:
1 package com.FM.ArrayListStudy; 2 3 import java.util.ArrayList; 4 import java.util.Comparator; 5 6 public class ComparatorInArrayListStudy01 { 7 public static void main(String[] args) { 8 ArrayList<Integer> list = new ArrayList<Integer>(); 9 list.add(1); 10 list.add(12); 11 list.add(3); 12 list.add(4); 13 list.add(3); 14 list.add(11); 15 list.add(7); 16 System.out.println(list);//排序之前的list 17 18 list.sort(new Comparator<Integer>() {//使用Comparator进行自然排序 19 @Override 20 public int compare(Integer one, Integer anotherOne) { 21 int compareTo = one.compareTo(anotherOne);//正序排序 22 //int compareTo = anotherOne.compareTo(one);//逆序排序 23 24 //比较结果为1则不操作 25 //比较结果为0则相等 26 //比较结果为-1则交换位置 27 System.out.println(anotherOne + " -- " + one + " --- " + compareTo); 28 return compareTo; 29 } 30 }); 31 System.out.println(list);//排序之后的list 32 } 33 }
运行结果:
2、依照比较的结果(-1,0,1)进行判断分组
示例代码如下:Apple类
1 package com.FM.ArrayListStudy; 2 3 public class Apple { 4 5 private Integer id; 6 private Integer size; 7 8 public Integer getId() { 9 return id; 10 } 11 12 public void setId(Integer id) { 13 this.id = id; 14 } 15 16 public Integer getSize() { 17 return size; 18 } 19 20 public void setSize(Integer size) { 21 this.size = size; 22 } 23 24 public Apple(Integer id, Integer size) { 25 super(); 26 this.id = id; 27 this.size = size; 28 } 29 30 @Override 31 public String toString() { 32 return "Apple [id=" + id + ", size=" + size + "]"; 33 } 34 35 }
示例代码如下:利用Comparator接口分组
1 package com.FM.ArrayListStudy; 2 3 import java.util.ArrayList; 4 import java.util.Comparator; 5 import java.util.List; 6 7 public class ComparatorInArrayListStudy02 { 8 public static void main(String[] args) { 9 ArrayList<Apple> list = new ArrayList<Apple>(); 10 list.add(new Apple(1, 81)); 11 list.add(new Apple(2, 76)); 12 list.add(new Apple(3, 91)); 13 list.add(new Apple(4, 84)); 14 list.add(new Apple(5, 79)); 15 list.add(new Apple(6, 87)); 16 list.add(new Apple(7, 85)); 17 list.add(new Apple(8, 83)); 18 list.add(new Apple(9, 91)); 19 System.out.println(list);//排序之前的list 20 21 List<List<Apple>> disPartList = disPart(list,new Comparator<Apple>(){ 22 @Override 23 public int compare(Apple o1, Apple o2) {//这里写具体的分组接口,分组方式可以使用对象内的属性的组合方式 24 if(o1.getSize()/10 == o2.getSize()/10){//将苹果Apple按照size分组,每10个size分为一组 25 return 0; 26 } 27 return 1; 28 } 29 }); 30 for(List lis : disPartList){//分别遍历每一组 31 System.out.println(lis); 32 } 33 } 34 35 /** 36 * 按照comparator进行分组的方法 37 */ 38 public static <T> List<List<T>> disPart(List<T> list, Comparator<? super T> c) { 39 ArrayList<List<T>> resultList = new ArrayList<List<T>>(); 40 for (T t : list) { 41 boolean flag = false; 42 for (int i = 0; i < resultList.size(); i++) { 43 if (c.compare(t, resultList.get(i).get(0)) == 0) {// 若匹配成功则加入resultList中的子元素 44 flag = true; 45 resultList.get(i).add(t); 46 break; 47 } 48 } 49 if (flag == false) {// 若flag为false则将此元素加入resultList为新元素 50 List<T> listIn = new ArrayList<T>(); 51 listIn.add(t); 52 resultList.add(listIn); 53 } 54 } 55 return resultList; 56 } 57 }
运行结果:
分组的方式很多,很多人也喜欢自己写遍历来分组
利用好Comparator接口进行分组能更好的重用,也更容易扩展!
以上!!