一、概述:
对一组数据进行排序(升序或降序),在Java中有很多方式,可以自己手写排序算法(冒泡、快速、二叉树排序等),但一般都采用JDK为我们提供的现有的2个接口,Comparable和Comparator。
二、相同点:
- 两者都是用来用作对象之间的比较,都可以自定义比较规则。
- 两者都是返回一个描述对象之间关系的int。
三、区别:
- Comparable是java.lang包下的,Comparator是java.util包的。
- 实现Comparable接口必须重写compareTo(T o)方法,实现Comparator接口必须重写compare(T o1,T o2)方法。.
- Comparable是内在比较器,实现这个接口的类的对象可以直接比较:this.compareTo(this),这个类也支持排序,由该类对象组成的集合可以直接使用Collections.sort方法排序,此外,“实现Comparable接口的类的对象”可以用作“有序映射(如TreeMap)”中的键或“有序集合(TreeSet)”中的元素,而不需要指定比较器。Comparator是外在比较器,如果想比较两个类又没有实现Comparable或者想实现自定义排序的,可以用Comparator。
- Comparator与Comparable同时存在的情况下,比较器Comparator优先级高。
- 使用Comparable需要修改原先的实体类,是属于一种自然排序,而Comparator 是不用修改原先的类的实现一个新的比较器 。Comparator实际应用广。
四、例子:
通俗来说,如果一个实体类实现了Comparable接口来实现排序规则,使用一段时间后,如果想去改变这个排序规则,基于“开闭原则”对修改关闭对扩展开放,我们可以通过Comparator接口来实现新的排序规则让实体类去采纳,使用一段时间后,如果还想改变,再通过Comparator接口实现一个新的排序规则即可。不影响类的封装性,易于扩展。
实体类Book实现了Comparable接口,比较规则是按书价大小。将多个Book对象存储在Set容器中,存储顺序是按照compareTo的规则。
package com.orange.sort; public class Book implements Comparable{ private String bookName; private int bookPrice; public Book() { } public Book(String bookName, int bookPrice) { this.bookName = bookName; this.bookPrice = bookPrice; } public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } public int getBookPrice() { return bookPrice; } public void setBookPrice(int bookPrice) { this.bookPrice = bookPrice; } @Override public String toString() { return "Book{" + "bookName='" + bookName + ''' + ", bookPrice='" + bookPrice + ''' + '}'; } @Override public int compareTo(Book o) { int minusPrice=this.getBookPrice()-o.getBookPrice(); return minusPrice; } }
测试:
@Test public void test(){ TreeSetset = new TreeSet<>(); Book book1 = new Book("A", 1); Book book2 = new Book("B", 5); Book book3 = new Book("C", 3); Book book4 = new Book("D", 4); set.add(book1); set.add(book2); set.add(book3); set.add(book4); for(Book book:set){ System.out.println(book); } }
结果:按照书价排序
Book{bookName='A', bookPrice='1'} Book{bookName='C', bookPrice='3'} Book{bookName='D', bookPrice='4'} Book{bookName='B', bookPrice='5'}
针对上述例子,此时如果想改变排序规则,在不破坏原实体类的封装性的前提下,可实现Comparator接口制定新规则,在创建TreeSet时,传入Comparator:
public void test2(){ TreeSetset = new TreeSet<>(new Comparator () { @Override public int compare(Book o1, Book o2) { return o1.getBookName().compareTo(o2.getBookName()); } }); Book book1 = new Book("A", 1); Book book2 = new Book("B", 5); Book book3 = new Book("C", 3); Book book4 = new Book("D", 4); set.add(book1); set.add(book2); set.add(book3); set.add(book4); for(Book book:set){ System.out.println(book); } }
结果:按照书名排序
Book{bookName='A', bookPrice='1'} Book{bookName='B', bookPrice='5'} Book{bookName='C', bookPrice='3'} Book{bookName='D', bookPrice='4'}
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)