1、内置引用数据类型比较(常用)

1.1  Comparable

1、整数、小数Integer Float Double 直接比较基本数据类型的大小

2、字符:比较的Unicode码只差

3、字符串:

1)如果其中一个是另外一个其实开始的子传,返回长度子差

2)否则返回第一个不相等的Unicode码之差

4、java.util.Date:根据日期的长整形数比较

1

 /**
* 引用数据类型的排序
* @author qjc
*
* 2016-3-10
*/
public class ComparableDemo {
/**
* 数组排序(使用泛型方法)
* @param arr
*/
public static <T extends Comparable<T>> void sort(T[] arr){
boolean sortede = true; //有序标示则不用比较
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-1-i; j++) {
sortede = true;
if(((Comparable)arr[j]).compareTo(arr[j+1]) > 0){
T temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
sortede = false;
}
if(sortede){ //减少趟数
break;
}
}
}
}
public static void main(String[] args) {
String[] arr = {"abc","ab","a"};
sort(arr);
for(String s : arr){
System.out.println(s);
}
//结果: a ab abc
}
}

1.2  Comparator

提供排序的比较器,业务比较器

实现java.util.Comparator接口

重写public intcompare(T o1,T o2)

作用:

解耦:独立于实体类

方便:便于应用各种排序规则

2

 /**
* 排序规则的业务类
* @author qjc
*
* 2016-3-10
*/
public class StringComp implements java.util.Comparator {
/**
* 按长度比较大小
* 正数: >0
* 负数: <0
* 0 :==
*/
@Override
public int compare(Object o1, Object o2) {
int len1 = ((String) o1).length();
int len2 = ((String) o2).length();
return len1 - len2;
}
} /**
* Comparator排序
* @author qjc
*
* 2016-3-10
*/
public class ComparatorDemo {
/**
* 数组的排序(升序)+Comparator接口
* @param arr
* @param comm
*/
public static <T> void sort(Object[] arr,Comparator<T> comm){
boolean sorted = true;
for (int i = 0; i < arr.length-1; i++) {
for (int j = 0; j < arr.length-1-i; j++) {
if(comm.compare((T)arr[j], (T)arr[j+1]) > 0){
Object temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
sorted = false;
}
if(sorted){
break;
}
}
}
}
@Test
public void testSort(){
String[] arr = {"dss","fdss","fefeef"};
sort(arr, new StringComp());
System.out.println(Arrays.toString(arr));
//输出结果: [dss, fdss, fefeef]
}
}

1.3 Collections之排序

Collections工具类,此类完全由在collection 上进行操作或返回 collection 的静态方法组成。

提供了大量便于处理容器的方法

关于排序:

1、public static <T extends Comparable<?super T>> void sort(List<T> list)

2、public static<T> void sort(List<T> list,Comparator<? super T> c)

2、引用类型(自定义)

2.1  Comparable

按业务规则排序:

1、实体类:java.lang.Comparable + compareTo

例3:

新闻信息排序:按时间(第一排序)、点击量(第二排序)、标题(第三排序)

/**
* 新闻条目实体类
* @author qjc
*
* 2016-3-10
*/
public class NewItem implements java.lang.Comparable<NewItem>{
//标题
private String title;
//点击量
private int hits;
//时间
private Date pubTime;
//时间降序(第一排序) + 点击量升序(第二排序) + 标题降序
@Override
public int compareTo(NewItem ntm) {
int result = 0;
//比较时间
result = - this.pubTime.compareTo(ntm.pubTime); //降序
if(0 == result){
//点击量
result = this.hits - ntm.hits; //升序
//点击量相同
if(0 == result){
//标题
result = - this.title.compareTo(ntm.title); //降序
}
}
return result;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("标题:").append(this.title);
sb.append("时间:").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.pubTime));
sb.append("点击量:").append(this.hits).append("\n");
return sb.toString();
}
//getter and setter...
} /**
*
* @author qjc
*
* 2016-3-10
*/
public class NewItemApp { @Test
public void test(){
List<NewItem> news = new ArrayList<>();
news.add(new NewItem("袁贵仁:十三五期间9年义务教育不会延长",100,
new Date(System.currentTimeMillis()-1000*60*60)));
news.add(new NewItem("沪指收跌2.02%危及2800点 分析:三因素影响A股",999,
new Date()));
news.add(new NewItem("女足回京球迷献吻 盼奥运进四强拿牌",888,
new Date(System.currentTimeMillis()+1000*60*60)));
System.out.println("排序前:"+news);
System.out.println("====================================");
//Collections工具类排序(默认升序)
Collections.sort(news);
System.out.println("排序后:"+news);
}
}

 输出结果:

排序前:

[标题:袁贵仁:十三五期间9年义务教育不会延长时间:2016-03-10 21:33:28点击量:100

,标题:沪指收跌2.02%危及2800点分析:三因素影响A股时间:2016-03-10 22:33:28点击量:999

,标题:女足回京球迷献吻盼奥运进四强拿牌时间:2016-03-1023:33:28点击量:888

]

====================================

排序后:

[标题:女足回京球迷献吻盼奥运进四强拿牌时间:2016-03-10 23:33:28点击量:888

,标题:沪指收跌2.02%危及2800点分析:三因素影响A股时间:2016-03-10 22:33:28点击量:999

,标题:袁贵仁:十三五期间9年义务教育不会延长时间:2016-03-1021:33:28点击量:100

]

2.2  Comparator

2、业务排序类:java.util.Comparator + compare

优点:

  • 解耦:与实体类分类
  • 方便:应对多变排序规则

例4:

按商品价格排序

 /**
* 商品类
* @author qjc
*
* 2016-3-10
*/
public class Goods {
//商品名
private String name;
//收藏量
private int fav;
//价格
private double price;
@Override
public String toString() {
return "商品名:"+this.name+",收藏量"+this.fav+",价格"+this.price+"\n";
}
//getter and setter...
} /**
* 按价格排序的业务类(降序)
* @author qjc
*
* 2016-3-10
*/
public class GoodsPriceComp implements java.util.Comparator<Goods>{ @Override
public int compare(Goods o1, Goods o2) {
return -(o1.getPrice()-o2.getPrice()>0 ? 1 : (o1.getPrice()==o2.getPrice())?0 : -1);
}
} /**
*
* @author qjc
*
* 2016-3-10
*/
public class GoodsApp {
@Test
public void test(){
List<Goods> list = new ArrayList<>();
list.add(new Goods("iphone 5SE",1800,3888));
list.add(new Goods("iphone 7",1998,5888));
list.add(new Goods("Galaxy S7",2000,4888));
System.out.println("排序前:"+list);
//排序
Collections.sort(list,new GoodsPriceComp());
System.out.println("排序后:"+list);
}
}

输出结果:

排序前:

[商品名:iphone 5SE,收藏量1800,价格3888.0

,商品名:iphone 7,收藏量1998,价格5888.0

,商品名:Galaxy S7,收藏量2000,价格4888.0

]

排序后:

[商品名:iphone 7,收藏量1998,价格5888.0

,商品名:Galaxy S7,收藏量2000,价格4888.0

,商品名:iphone 5SE,收藏量1800,价格3888.0

]

3.3  TreeSet和TreeMap集合排序

3.3.1 TreeSet:
     数据元素可以排序且不可以重复

  • 确保元素实体可以排序
  • 排序比较器

publicTreeSet(Compartor<? super E> comparator)

对比Set接口:HashSet,元素必须重写hashcode和equals方法。

去重:比较等于0即重复

例5:使用TreeSet无参构造实体类实现Comparable

/**
* 实体类实现Comparable
* @author qjc
*
* 2016-3-11
*/
public class Worker implements java.lang.Comparable<Worker>{
//工种
private String type;
//工资
private double salary;
//按工资升序
@Override
public int compareTo(Worker o) {
return this.salary>o.salary?1:this.salary==o.salary?0:-1;
}
//getter and setter..
} /**
* 使用Comparable排序
* @author qjc
*
* 2016-3-11
*/
public class TreeSetDemo2 {
public static void main(String[] args) {
Worker w1 = new Worker("教师",12000);
Worker w2 = new Worker("公务员",8000);
Worker w3 = new Worker("程序猿",6000);
TreeSet<Worker> employeess = new TreeSet<>();
employeess.add(w1);
employeess.add(w2);
employeess.add(w3);
System.out.println(employeess);
}
}

例6:使用TreeSet带参构造使用Comparator比较器

 public class Person {
private String name;
//帅气指数
private int handsome;
//geter and setter..
} /**
* 提供解耦方式排序
* @author qjc
*
* 2016-3-11
*/
public class TreeSetDemo {
public static void main(String[] args) {
Person p1 = new Person("刘德华", 2000);
Person p2 = new Person("梁朝伟", 2200);
Person p3 = new Person("鹿晗", 1500);
//依次放到TreeSet容器中,使用排序的业务类(内部类)
TreeSet<Person> persons = new TreeSet<>(
new java.util.Comparator<Person>(){
@Override
public int compare(Person o1, Person o2) {
//降序
return -(o1.getHandsome() - o2.getHandsome());
}
}
);
//TreeSet 在添加数据时排序
persons.add(p1);
persons.add(p2);
persons.add(p3);
System.err.println(persons);
}
}

注意:

在添加数据时排序,数据更改不会影响原来的顺序,不要修改数据,否则可能重复。 ---可以使用final修饰

3.3.2 TreeMap:

  • 确保key可以排序
  • 提供比较器

publicTreeMap(Comparator<? super K> comparator)

例:与TreeSet同理


总结:

相同点:

Comparable和Comparator都是用来实现集合、数组中元素的比较、排序的

不同点:

1、Comparable是在集合内部定义的方法实现的排序,而Comparator是在集合外部实现的排序,

所以,如想实现排序,就需要在集合外定义 Comparator接口的方法或在集合内实现 Comparable接口的方法。

Comparator位于包java.util下,而Comparable位于包java.lang下

2、Comparable是一个对象,本身就已经支持自比较所需要实现的接口(如Integer、String、Float、Double、Date等底层都实现了Comparable接口 自己就可以完成比较大小操作)

自定义的类要在加入list容器中后能够排序,可以实现Comparable接口,在用Collections类的sort方法排序时,如果不指定Comparator,那么就以自然顺序排序,这里的自然顺序就是实现Comparable接口设定的排序方式,并且是升序。

3、Comparator是一个专用的比较器,当这个对象不支持自比较或者自比较函数不能满足你的要求时,你可以写一个比较器来完成两个对象之间大小的比较。

Comparator 与实体类分类于系统解耦优点,比如说例4按商品排序,如果需要按名称排序(或改升序、降序),只需要在业务类修改,在应变多变规则时方便程序修改和维护。所以推荐使用Comparator

集合框架学习之排序Comparable&Comoarator的更多相关文章

  1. JavaSE中Collection集合框架学习笔记(3)——遍历对象的Iterator和收集对象后的排序

    前言:暑期应该开始了,因为小区对面的小学这两天早上都没有像以往那样一到七八点钟就人声喧闹.车水马龙. 前两篇文章介绍了Collection框架的主要接口和常用类,例如List.Set.Queue,和A ...

  2. JavaSE中Collection集合框架学习笔记(2)——拒绝重复内容的Set和支持队列操作的Queue

    前言:俗话说“金三银四铜五”,不知道我要在这段时间找工作会不会很艰难.不管了,工作三年之后就当给自己放个暑假. 面试当中Collection(集合)是基础重点.我在网上看了几篇讲Collection的 ...

  3. Java集合框架实现自定义排序

    Java集合框架针对不同的数据结构提供了多种排序的方法,虽然很多时候我们可以自己实现排序,比如数组等,但是灵活的使用JDK提供的排序方法,可以提高开发效率,而且通常JDK的实现要比自己造的轮子性能更优 ...

  4. Java集合框架学习笔记

    集合类的由来:对象用于封装特有数据,对象多了需要存储,如果对象的长度不确定,就使用集合存储. 集合特点1.用于存储对象的容器.2.集合的长度可变.3.集合中不可以存储基本类型 集合容器因为内部的数据结 ...

  5. Java—集合框架 Collections.sort()、Comparable接口和Comparator接口

    Collentions工具类--java.util.Collections Collentions是Java集合框架中,用来操作集合对象的工具类,也是Java集合框架的成员,与List.Map和Set ...

  6. Java集合框架学习(一)List

    先附一张Java集合框架图. 从上面的集合框架图可以看到,Java集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射.Coll ...

  7. 【java基础 11】java集合框架学习

    导读:本篇博客主要是从整体上了解java的集合框架,然后主要介绍几个自己在项目中用到的结构,比如说:hashtable.hashmap.hashset.arraylist等! 一.宏观预览 从宏观上看 ...

  8. 集合框架学习之Guava Collection

    开源工具包: Guava : Google Collection Apache:Commons Collecton 1.1 Google Collections Guava:google的工程师利用传 ...

  9. Java集合框架学习

    集合框架 集合框架的目标 该框架必须是高性能的.基本集合(动态数组,链表,树,哈希表)的实现必须是高效的. 该框架允许 不同类型的集合,以类似的方式工作,具有高度的互操作性. 对一个集合的扩展和适应必 ...

随机推荐

  1. 你应该知道的JavaScript中NaN的秘密

    NaN,不是一个数字,是一种特殊的值来代表不可表示的值,使用typeof或其他任何与之比较的处理方式,‘NaN’则会引起一些混乱, 一些操作会导致NaN值的产生.这里有些例子: Math.sqrt(- ...

  2. hdu 4859 海岸线 最小割

    海岸线 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=4859 Description 欢迎来到珠海! 由于土地资源越来越紧张,使得许多海滨城市都只能 ...

  3. C#操作Excel(2)-- 打开-读取Excel文档

    由于要为某软件实现导出Excel功能,故有此文. 本文的开发环境是Visual Studio 2010 ,C#, Excel 2007. 新建C#工程后打开Solution Explorer,可以看到 ...

  4. Android——ViewGroup的一个用法实例(转载)

    找了很久,终于找到了. <?xml version="1.0" encoding="UTF-8" ?> <merge xmlns:androi ...

  5. 利用FluorineFX录制音频与视频

    要做一个完整的录制程序,处理RPC请求的类不仅要继承ApplicationAdapter,还要继承IStreamService接口,该接口定义了play(),pause(),publish(),cre ...

  6. alue of type java.lang.String cannot be converted to JSONObject

    /** * 4.0以下系统处理掉返回json的BOM头 * * @param jsonStr * @return */ public static String getJson(String json ...

  7. IE9-10 option BUG

    IE 9-10下如果option元素没有定义value而在设置innerText时没有把两边的空白去掉,那么 取el.text,浏览器会进行trim, 并且伪造一个value值,此值会在刚才trim的 ...

  8. oracle连接错误

    公司用的数据库,动不动会出现一些问题.但是都是大家比较常见的.所以,贴出来给大家看看1,oracle启动数据库时报错:SQL> startup;ORA-01078: failure in pro ...

  9. PHP经验——PHPDoc PHP注释的标准文档(翻译自Wiki)

    文档注释,无非“//”和“/**/”两种 ,自己写代码,就那么点,适当写几句就好了:但是一个人总有融入团队的一天,团队的交流不是那几句注释和一张嘴能解决的,还需要通用的注释标准. PHPDoc是PHP ...

  10. linux连接静态库

    在项目中发现,使用 -l连接某个库时,如果存在同名的静态库(.a)和动态库(.so),默认会连接.so 那么如何指定连接静态库呢?如果有多个库,有些要连接静态库.有些要连接动态库,连接选项该如何指定呢 ...