该代码内容较为冗长,其内容大值可分为这三个部分:
1、Collections的排序方法
2、内部类的放置位置对其调用的影响
3、匿名类通过Comparator接口实现(其中匿名类还可通过Lambda接口实现))
import java.util.ArrayList;
import java.util.*;
import java.util.List;
/**
* class Rule implements Comparator {
* //Comparator是方法接口
*
* @Override public int compare(Object o1, Object o2) {
* if (o1 instanceof Student && o2 instanceof Student) {
* Student s1 = (Student) o1;
* Student s2 = (Student) o2;
* if (s1.getId() > s2.getId()) {
* return 1;
* } else if (s1.getId() < s2.getId()) {
* return -1;
* }
* return 0;
* }
* throw new RuntimeException("必须是Student类型");
* }
* }
*/
//当我们把这个规则类放到类外面时,
//我们仍然可以用方法级接口调用到该方法。
//即java.util.Collections.sort(s,new Rule());
//Collections是操作所有集合的类
public class TestCollections {
/**
* class Rule implements Comparator {
* //Comparator是方法接口
* @Override
* public int compare(Object o1, Object o2) {
* if (o1 instanceof Student && o2 instanceof Student) {
* Student s1 = (Student) o1;
* Student s2 = (Student) o2;
* if (s1.getId() > s2.getId()) {
* return 1;
* } else if (s1.getId() < s2.getId()) {
* return -1;
* }
* return 0;
* }
* throw new RuntimeException("必须是Student类型");
* }
* }
*/
//因为除了学生类要用,其他地方用不到,
//我们可以把这个规则定义到主类和主函数中间。
//但是,我们将这个规则类定义到主类里头之后还是出错了。
//主要原因就是,凡是放到主类里头的类。
//我们只有在new主类对象的时候,才会给主类分配内存,
//包括内部类的定义。
//也就是说,当我们通过 java.util.Collections.sort(s,new Rule());
//在主函数里new这个规则类的时候,根本就不存在,连遍历都不存在。
//这时候,我们在该规范类下面,主函数之上new这个规范类。
//即Rule r=new Rule();接下来,我们这样new————
//java.util.Collections.sort(s,new TestCollections.r);
//就可以给该类分配内存,并访问类里面的属性。
//到这里也就说明了,内部的属性必须依赖外部的对象的条件。
/**
* static class Rule implements Comparator {
* ......
* }
*/
//这里,静态的东西不用new,在加载的时候直接分配内存。
//但是,这里就要求静态类的东西必须规定用外部类的名字来引用,即
//java.util.Collections.sort(s,new TestCollections.Rule());
public static void main(String[] args) {
List s = new ArrayList();
s.add(120);
s.add(23);
s.add(33);
s.add(76);
System.out.println(s);
java.util.Collections.sort(s);
//sort方法是排序的
System.out.println(s);
s = new ArrayList();
s.add(new Student(2000, "张三", 'm'));
s.add(new Student(2001, "李四", 'm'));
s.add(new Student(1999, "王麻子", 'm'));
System.out.println(s);
// Collections.sort(s);
//因为我们这个类只用一次,那么我们就可以定义到主方法里头。
//即该规则类就成为了内部类,也不用使用静态方法了。
//不过这里需要注意的一点就是————因为是在主方法里头,
//那么代码就是顺序执行的。
//如果我们将java.util.Collections.sort(s,new Rule());
//放在了该内部类的前面,按照代码执行顺序来说,
//我们就没有给内部类分配内存,该行代码报错。
//所以,我们按照代码执行顺序,将该行代码放在内部类之后就对了。
/**
* 局部类
*/
//这里就是,我们自己传两个对象。
//然后这方法帮我们比较这两个对象的大小。
// class Rule implements Comparator {
// //Comparator是方法接口
// @Override
// public int compare(Object o1, Object o2) {
// if (o1 instanceof Student && o2 instanceof Student) {
// Student s1 = (Student) o1;
// Student s2 = (Student) o2;
// if (s1.getId() > s2.getId()) {
// return 1;
// } else if (s1.getId() < s2.getId()) {
// return -1;
// }
// return 0;
// }
// throw new RuntimeException("必须是Student类型");
// }
// }
//
// java.util.Collections.sort(s, new Rule());
// //方法级接口,也就是在接口里面定义了一个方法。
// System.out.println(s);
/**
* 匿名类
*/
//这里new的Comparator接口后面还有大括号,
//也就说明,我们new的是该方法类里的子类,
//而大括号里面的内容即是子类的定义。
//而该子类现在没有名字,只有编译完之后,编译器给该子类名字。
//我们用该类的时候根本就不知道该类的名字,因为没有必要知道。
//因为只在new的参数这里去用,在该大括号里的子类里去用,别的地方用不到。
//而定义无非就是实现这个接口。
//用Comparator接口写匿名类
/** java.util.Collections.sort(s, new Comparator() {
* ......
* });
*/
//用Lambda接口写匿名类
java.util.Collections.sort(s, (Comparator) (o1, o2) -> {
if (o1 instanceof Student && o2 instanceof Student) {
Student s1 = (Student) o1;
Student s2 = (Student) o2;
if (s1.getId() > s2.getId()) {
return 1;
} else if (s1.getId() < s2.getId()) {
return -1;
}
return 0;
}
throw new RuntimeException("必须是Student类型");
});
System.out.println(s);
}
}
输出结果
[120, 23, 33, 76]
[23, 33, 76, 120]
[Student{id=2000, name='张三', sex=m}, Student{id=2001, name='李四', sex=m}, Student{id=1999, name='王麻子', sex=m}]
[Student{id=1999, name='王麻子', sex=m}, Student{id=2000, name='张三', sex=m}, Student{id=2001, name='李四', sex=m}]