本文主要内容:
1.引用类型的排序
2.接口Comparable<E>
3.接口Comparator<E>
4.泛型
- 排序people
无法直接做,一个person类的引用无法与另一个person类的引用做大小比较
- 引入接口
Comparable<E>
(相等性的比较)
天然自身有序,打印出有序
覆写一个方法:如果<0,this指向的对象小,反之,this指向的对象大
(1)让person实现该接口Comparable<Person>
(2)覆写接口中的方法comparetTo(Person o):该方法返回小于0,即this比较小,该方法返回0,即相等,该方法返回大于0,即this比较大。
- 引入另一个接口
Comparator<E>
脱离类的存在而实现(比较器)
类本身不具备可比较的特性,专门有一个类比较该类的大小(比较器)
(1)覆写compare方法(直接比较两个对象)
(2)在写排序的方法中加入Comparator<Person> comparator
参数
- 对象的比较总结
覆写Object.equals:比较两个对象是否相等
实现Comparable接口,覆写CompareTo:比较两个对象的自然大小关系
定义一个比较器,实现Comparator接口,覆写Compare:通过一个和类不相关的方式,比较两个对象的大小
对象的排序:库中的方法
(1)Arrays.sort(people):自然排序
(2)Arrays.sort(people,new personRankComparator()):比较器进行比较
(3)List中的排序:利用比较器进行比较
- 泛型
- 实现泛型类
实现一个顺序表的泛型类
public class MyArrayList<E>[形参] implements List<E>[实参]{构造方法有所不同}
- 泛型的类型擦除问题
(1)已知泛型是工作在编译期间的一种机制
(2)编译器(javac)在编译期间,将E变换为一种具体的类型——类型擦除
(3)定义的边界问题MyArrayList{}:E必须是Integer类型的子类型包括Integer本身——类型擦除为Integer类型(在定义过程中)
了解:泛型
MyArrayList<Integer>
MyArrayList<String>
MyArrayList<Double>
- 泛型的父类和子类问题
MyArrayList<Object>
MyArrayList<Number>
MyArrayList<Integer>
虽然Integer继承Number,Number继承Object,但是三个MyArrayList泛型毫无关系,为了解决以上问题,引入泛型类(泛型方法中)通配符。
- 通配符
MyArrayList<?> list;
MyArrayList<Object> objectList;
MyArrayList<Integer> integerList;
list = objectList;list = integerList
- 通配符的上下界(在使用过程中)
MyArrayList<? extends Integer> list;//上界
MyArrayList<? super Integer> list;//下界
泛型方法:在返回值前面加泛型
代码演示:
//需要一个实现Comparable接口的person类、一个实现Comparator接口的实现类、一个测试类
public class Person implements Comparable<Person>{
public int age;
public int rank;
public String name;
@Override
public String toString() {
return String.format("{age="+age+"}"+"{rank="+rank+"}");
}
// public void getInfo(){
// System.out.println("age="+age);
// }
@Override
public int compareTo(Person o) {
if(this.age<o.age){
return -1;
}else if(this.age == o.age){
return 0;
}else{
return 1;
}
}
}
public class personRankComparator implements Comparator<Person> {
@Override
public int compare(Person o1, Person o2) {
return o1.rank-o2.rank;
}
}
public class Solution2 {
public static void swap(Person[] array,int a,int b){
Person temp = array[a];
array[a] = array[b];
array[b] = temp;
}
//引入接口comparable使得天然自身有序
public static void bubbleSort(Person[] array){
for(int i = 0;i<array.length-1;i++){
for(int j = 0;j<array.length-i-1;j++){
int result = array[j].compareTo(array[j+1]);
if(result>0){
swap(array,j,j+1);
}
}
}
}
//使用比较器
public static void bubbleSort1(Person[] array, Comparator<Person> comparator){
for(int i = 0;i<array.length-1;i++){
for(int j = 0;j<array.length-i-1;j++){
int result = comparator.compare(array[j],array[j+1]);
if(result>0){
swap(array,j,j+1);
}
}
}
}
public static void main(String[] args) {
Person[] person = new Person[20];
Random random = new Random(20190902);
for (int i = 0; i < person.length; i++) {
person[i] = new Person();
person[i].age = random.nextInt(100);
person[i].rank = random.nextInt(50);
}
System.out.println(Arrays.toString(person));
// for(int i = 0;i<person.length;i++){
// person[i].getInfo();
// }
bubbleSort(person);
bubbleSort1(person,new personRankComparator());
System.out.println(Arrays.toString(person));
}
}
//运行结果
[{age=19}{rank=6}, {age=55}{rank=5}, {age=26}{rank=44}, {age=15}{rank=40}, {age=6}{rank=9}, {age=69}{rank=43}, {age=90}{rank=37}, {age=40}{rank=26}, {age=53}{rank=45}, {age=17}{rank=46}, {age=39}{rank=17}, {age=72}{rank=19}, {age=62}{rank=28}, {age=7}{rank=27}, {age=19}{rank=31}, {age=48}{rank=37}, {age=69}{rank=30}, {age=50}{rank=38}, {age=73}{rank=26}, {age=30}{rank=37}]
[{age=55}{rank=5}, {age=19}{rank=6}, {age=6}{rank=9}, {age=39}{rank=17}, {age=72}{rank=19}, {age=40}{rank=26}, {age=73}{rank=26}, {age=7}{rank=27}, {age=62}{rank=28}, {age=69}{rank=30}, {age=19}{rank=31}, {age=30}{rank=37}, {age=48}{rank=37}, {age=90}{rank=37}, {age=50}{rank=38}, {age=15}{rank=40}, {age=69}{rank=43}, {age=26}{rank=44}, {age=53}{rank=45}, {age=17}{rank=46}]
public class MyArrayList<E> {
private E[] array;
private int size;
@SuppressWarnings("unchecked")
public MyArrayList(){
//泛型无法定义泛型数组
//压制警告
array = (E[])new Object[100];
size = 0;
}
public void add(E e){
array[size++] = e;
}
public void remove(){
//size--;会引起内存泄漏,这种写法没有被GC判定为死掉
array[--size] = null;
}
}