Comparable,Comparator
Comparable:
类实现 Comparable 接口即可进行自然排序,排序是根据类所实现的 compareTo() 方法,小于,等于,大于的比较结果分别用负整数,0,正整数作为返回值表示;
实现了 Comparable 的类可作为有序映射中的键或者有序集合中的元素,无需指定比较器(Comparator);
comparaTo() 应该与 equals() 保持一致,即comparaTo(obj) 返回 0 的情况下,equals(obj) 需要返回 true,虽然不是必需;
了解 compareTo() 方法:
除了上述的要求,还有以下要求:
1,确保如果 y.compareTo(x) 抛出异常,x.compareTo(y) 也要抛出异常;
2,e.compareTo(null) 会抛出 NPE;
3,实现类确保关系是可传递的:(x.compareTo(y)>0 && y.compareTo(z)>0) 意味着 x.compareTo(z)>0;
4,最后,实现者必须确保 x.compareTo(y)==0 意味着对于所有的 z,都存在 sgn(x.compareTo(z)) == sgn(y.compareTo(z))。 强烈推荐 (x.compareTo(y)==0) == (x.equals(y)) 这种做法,但并不是 严格要求这样做。
在前面的描述中,符号 sgn(expression) 指定 signum 数学函数,该函数根据 expression 的值是负数、零还是正数,分别返回 -1、0 或 1 中的一个值。
上代码:
public class Student implements Comparable<Student>{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } @SuppressWarnings("cast") @Override public int compareTo(Student student) { if (student == null) { throw new NullPointerException("compareTo 的对象不能为 null。"); } if (!(student instanceof Student)) { throw new ClassCastException("compareTo 的对象必须是 Student 实例。"); } int len1 = this.name.length(); int len2 = student.name.length(); if (len1 > len2) { return 1; } else if (len1 < len2) { return -1; } else { return 0; } } }
Comparator:
实现 Comparator 接口的类的实例,可以被传递到 sort 方法(如 Collections.sort 或 Arrays.sort),从而允许在排序顺序上实现精确控制;也可以使用 Comparator 来控制某些集合类实例的元素的顺序;
实现 Comparator 接口需要实现 compare() 方法,实现该方法的要求与 compareTo() 方法一致;
需要注意的是,TreeSet 判断元素重复,是通过调用 compare() 方法,通过其是否返回 0 进行判断,Set 的常规判断是通过 equals() 方法进行判断的;所以使用 Comparator 用在 TreeSet 上时,实现 compare() 方法需要注意,compare() 方法需要与 需要被排序的对象类型的 equals() 方法一致,这样就能同时符合 Set 的常规判断标准;
上代码:
public class StringComparator implements Comparator<String>{ @Override public int compare(String str1, String str2) { int len1 = str1.length(); int len2 = str2.length(); if (len1 > len2) { return 1; } else if (len1 < len2) { return -1; } else { return 0; } } }
public class Test { public static void main(String[] args) { Set<String> set = new TreeSet<>(new StringComparator()); set.add("000"); set.add("0"); set.add("000000"); System.out.println(set); } }
public class Test { public static void main(String[] args) { List<String> list = new ArrayList<>(); list.add("000"); list.add("0"); list.add("000000"); Collections.sort(list, new StringComparator()); System.out.println(list); } }
虽然说建议 compareTo() compare() 方法与 equals() 方法保持一致,但有时为了实现某些业务逻辑,违反这个建议比较好,那只要在方法说明这个方法与 equals() 方法不一致即可;
注意:Collections.sort() 方法,compare() 返回 -1,表示把 o1 排在 o2 前面;
以上。
浙公网安备 33010602011771号