1 Collection
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)。一些 Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection派生的两个接口是List和Set。
如何遍历Collection中的每一个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子即可逐一访问Collection中每一个元素。
// 典型的用法如下:
Iterator it = collection.iterator(); // 获得一个迭代子
while(it.hasNext()) {
Object obj = it.next(); // 得到下一个元素
}
2 Collections.sort
2.1 compare(T o1, T o2)是中的o1,o2代表什么,是怎么实现排序的?怎么和compareTo()配合使用?
o1 和 o2 每次只取一个数据,就一次只比较两个数据,o1 取后一个数,o2 取前一个数。假如比较 7,8,9,5,6,那么第一次比较 o1 先取 8,o2 取 7。
(1)compare方法>0,因为 o1 取后一个数,o2 取前一个数,所以前一个数和后一个数不交换;
(2)compare方法<0,交换。
o1.compareTo(o2)
会返回一个int值,如果0说明o1和o2相等;如果返回负值,那么o1和o2会倒序排序;返回正值,那么o1和o2会正序排序。
2.2 问题
(1)注意问题:修复Comparison method violates its general contract!
2.3 典型的升序
(1)引用类型比较
public static void main(String[] args) {
List<Integer> list = Arrays.asList(6,7,5,8,4,3,9,2,0,1,12,34,56,null,78,94);
System.out.println(list);
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer lhs, Integer rhs) {
if (lhs == null && rhs == null) {
return 0;
}
if (lhs == null) {
return -1;
}
if (rhs == null) {
return 1;
}
return lhs.compareTo(rhs);
}
});
System.out.println(list);
}
(2)基本类型比较
public static void main(String[] args) {
List<Integer> list = Arrays.asList(6,7,5,8,4,3,9,2,0,1,12,34,56,null,78,94);
System.out.println(list);
Collections.sort(list, new Comparator<Integer>() {
// 基本类型比较
@Override
public int compare(Info lhs, Info rhs) {
if (lhs == null && rhs == null) {
return 0;
}
if (lhs == null) {
return -1;
}
if (rhs == null) {
return 1;
}
int time = lhs.getTime() - rhs.getTime();
if (time > 0) {
return 1;
} else if (time < 0) {
return -1;
} else {
return 0;
}
}
});
System.out.println(list);
}
(3)简洁版
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer lhs, Integer rhs) {
if (lhs == null && rhs == null) {
return 0;
}
if (lhs == null) {
return -1;
}
if (rhs == null) {
return 1;
}
return lhs - rhs;
}
});
(2)运行结果
[6, 7, 5, 8, 4, 3, 9, 2, 0, 1, 12, 34, 56, null, 78, 94]
[null, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 34, 56, 78, 94]
(3) 分析
上面的compare函数,o1.compareTo(o2) > 0那么说明此时o1要大于o2,而此时return 1,将o1和o2对调(重载的compare返回值大于0那么就会对调)。也就是小的数放在左边,大数放在右边,这就是典型的升序。
2.2 典型的降序
(1)代码
public static void main(String[] args) {
List<Integer> list = Arrays.asList(6,7,5,8,4,3,9,2,0,1,12,34,56,null,78,94);
System.out.println(list);
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer lhs, Integer rhs) {
if (lhs == null && rhs == null) {
return 0;
}
if (lhs == null) {
return -1;
}
if (rhs == null) {
return 1;
}
return rhs.compareTo(lhs);
}
});
System.out.println(list);
}
(2)简洁版
Collections.sort(list, new Comparator<Integer>() {
@Override
public int compare(Integer lhs, Integer rhs) {
if (lhs == null && rhs == null) {
return 0;
}
if (lhs == null) {
return -1;
}
if (rhs == null) {
return 1;
}
return rhs - lhs;
}
});
(3)运行结果
[6, 7, 5, 8, 4, 3, 9, 2, 0, 1, 12, 34, 56, null, 78, 94]
[94, 78, 56, 34, 12, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0, null]
(4) 分析
o1.compareTo(o2) > 0,说明此时o1要大于o2,而此时return -1;小于0,所以o1和o2不用对调(重载的compare返回值大于0那么就会对调)。大数o1在左边,小数o2在右边,这就是典型的降序。
3 Comparator和Comparable比较
3.1 Comparator是比较器接口
(1)Comparator是比较器,若需要控制某个类的次序,可以建立一个“该类的比较器”来进行排序。
(2)Comparator的定义如下:
public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
}
(3)将Person按照age进行降序排序
private static class DescAgeComparator implements Comparator<Person> {
@Override
public int compare(Person p1, Person p2) {
return p2.getAge() - p1.getAge();
}
}
3.2 Comparable是排序接口
(1)Comparable是排序接口;若一个类实现了Comparable接口,就意味着“该类支持排序”。
(2)Comparable接口定义如下:
public interface Comparable<T> {
public int compareTo(T o);
}
说明:假设我们通过 x.compareTo(y) 来“比较x和y的大小”。若返回“负数”,意味着“x比y小”;返回“零”,意味着“x等于y”;返回“正数”,意味着“x大于y”。
(3)Person类实现了Comparable接口,因此它能被排序
private static class Person implements Comparable<Person>{
int age;
String name;
// 实现 “Comparable<String>” 的接口,即重写compareTo<T t>函数。这里是通过“person的名字”进行比较的
@Override
public int compareTo(Person person) {
return name.compareTo(person.name);
//return this.name - person.name;
}
}