Java集合(一)--Comparable和Comparator
Comparable:
是集合内部的方法实现的排序,只有一个方法
public interface Comparable<T> {
public int compareTo(T o);
}
对于String和一些基本数据类型,默认实现了Comparable 接口,实现了compareTo方法,可以直接使用。
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { public int compareTo(String anotherString) { int len1 = value.length; int len2 = anotherString.value.length; int lim = Math.min(len1, len2); char v1[] = value; char v2[] = anotherString.value; int k = 0; while (k < lim) { char c1 = v1[k]; char c2 = v2[k]; if (c1 != c2) { return c1 - c2; } k++; } return len1 - len2; } } public final class Integer extends Number implements Comparable<Integer> { public int compareTo(Integer anotherInteger) { return compare(this.value, anotherInteger.value); } }
使用场景:
同一个类的两个对象相互比较,类内部的比较
可以进行排序,但是一定要实现Comparable,否则出现异常
Collections.sort()和Arrays.sort()内部都有应用
使用样例:
@Slf4j @Data @AllArgsConstructor public class TestUnit implements Comparable<TestUnit>{ private String name; private Integer age; @Override public int compareTo(TestUnit o) { return this.age.compareTo(o.age); } public static void main(String[] args) { List<TestUnit> list = new ArrayList<TestUnit>(); list.add(new TestUnit("a",2)); list.add(new TestUnit("b",1)); list.add(new TestUnit("c",3)); System.out.println(list); Collections.sort(list); System.out.println(list);
TestUnit unit = new TestUnit("a", 1);
TestUnit unit1 = new TestUnit("b", 2);
System.out.println(unit.compareTo(unit1));
} }
结果:
[TestUnit(name=a, age=2), TestUnit(name=b, age=1), TestUnit(name=c, age=3)] [TestUnit(name=b, age=1), TestUnit(name=a, age=2), TestUnit(name=c, age=3)]
-1
Comparator:
是集合外部的方法实现的排序,多个方法
public interface Comparator<T> { int compare(T o1, T o2); public static <T> Comparator<T> comparingInt(ToIntFunction<? super T> keyExtractor) { Objects.requireNonNull(keyExtractor); return (Comparator<T> & Serializable) (c1, c2) -> Integer.compare(keyExtractor.applyAsInt(c1), keyExtractor.applyAsInt(c2)); } }
使用场景:
Comparator接口代码更加灵活,可以定义某个类的多个比较器,以满足不用的需求,而不改变对象自身,而用一个策略对象来改变对象的比较
行为(策略模式)。
使用样例:
@Slf4j @Data @AllArgsConstructor @NoArgsConstructor public class TestUnit implements Comparator<TestUnit> { private String name; private Integer age; public static void main(String[] args) { List<TestUnit> list = new ArrayList<TestUnit>(); list.add(new TestUnit("a",2)); list.add(new TestUnit("b",1)); list.add(new TestUnit("c",3)); System.out.println(list); Collections.sort(list, new TestUnit()); System.out.println(list); TestUnit unit = new TestUnit("a", 1); TestUnit unit1 = new TestUnit("b", 2); System.out.println(unit.compare(unit, unit1));; } @Override public int compare(TestUnit o1, TestUnit o2) { return o1.age - o2.age; } }
结果:
[TestUnit(name=a, age=2), TestUnit(name=b, age=1), TestUnit(name=c, age=3)] [TestUnit(name=b, age=1), TestUnit(name=a, age=2), TestUnit(name=c, age=3)] -1
注意事项:
无论是Comparable还是Comparator实现类在重写compareTo、compare方法时,一般要求compare(o1,o2))==0的逻辑结果要和o1.equals(o2)
保持一致。
总结:
(1)如果比较的方法只用在一个类中,则该类实现Comparable接口就可以
(2)如果比较的方法在很多类中需要用到,就自己写个类实现Comparator接口,实现松耦合
(3)在用Collections类的sort方法排序时,若不指定Comparator,那就以自然顺序排序(自然顺序就是实现Comparable接口设定的排序方式)