Java中的冒泡排序,Comparator接口和Comparable接口的简单使用
冒泡排序
冒泡排序是一种常见的排序方法,按照一定的规则(比如从小到大或者从大到小的顺序)对一组数据进行排序
。而在Java开发中,也经常用到冒泡排序。我们就以下面的一个例子来讲解冒泡排序算法。
给定一个数组:
int[] arr = {9, 3, 1, 7, 5};
现在要求对这个数组进行升序排列。
不妨这样思考:
第一轮:将数组中的从第二位开始,每个数都和第一个数进行比较,将这两个数中最小的数放到数组中的第一个位置,可获得如下比较过程:
初始状态:9,3,1,7,5
第1步:3,9,1,7,5;——3<9,3和9互换
第2步:1,9,3,7,5;——1<3,1和3互换
第3步:1,9,3,7,5;——7>1,不用互换
第4步:1,9,3,7,5;——5>1,不用互换
经过第一轮的比较之后,整个数组中的最小值就被放在了数组的第一个位置。接着比较第二轮。
第二轮:因为数组中的第一个数已经是整个数组中最小的数了,因此就不用从数组中的第一个数开始比较了,此时应该从第三位(第三位索引为2)开始,每个数都和第二个数进行比较,将这两个数中最小的数放到数组中的第二个位置,可获得如下比较过程:
初始状态:1,9,3,7,5
第1步:1,3,9,7,5;——3<9,3和9互换
第2步:1,3,9,7,5;——7>3,不用互换
第3步:1,3,9,7,5;——5<3,不用互换
经过第二轮比较之后,整个数组中除了第一位外,最小的数已经放到了数组的第二个位置。接着比较第三轮。
第三轮:因为数组中的前两个数已经是整个数组中最小的且已经是从小到大排好顺序的,因此应该从第四位(第四位索引为3)开始,每个数都和第三个数进行比较,将这两个数中最小的数放到数组中的第三个位置,可获得如下比较过程:
初始状态:1,3,9,7,5
第1步:1,3,7,9,5;——7<9,7和9互换
第2步:1,3,5,9,7;——5<7,5和7互换
第四轮:数组中的前三个数已经按照从小到达的顺序排序了,因此应该从第五位(第五位索引为4)开始,每个数都和第四个数进行比较,将这两个数中最小的数放到数组中的第四个位置,可获得如下比较过程:
初始状态:1,3,5,9,7;
第1步:1,3,5,7,9;——7<9,7和9互换
经过4轮比较之后,数组就按照从小到大的顺序排序完成。
最后用Java代码实现的结果如下:
package com.bjsxt.sort_bubble;/*** 冒泡排序(从小到大排列)* @author WL20180723**/
public class BubbleSort {public static void main(String[] args) {int[] arr = {9, 3, 1, 7, 5};System.out.print("排序前:");printArr(arr);for(int i = 0; i < arr.length - 1; i++) {for(int j = i + 1; j < arr.length; j++) {if(arr[i] > arr[j]) {int temp = arr[i];arr[i] = arr[j];arr[j] = temp;}}}System.out.print("排序后:");printArr(arr);}/*** 打印数组* @param arr 数组*/public static void printArr(int[] arr) {for(int i : arr) {System.out.print(i + "\t");}System.out.println();}}
程序输出结果如下:
排序前:9 3 1 7 5
排序后:1 3 5 7 9
其实冒泡排序的书写代码方式有很多,但是基本的思想基本都是一样的。
Java内置类型的比较
String类型的比较
String类型提供了int compareTo(String str)方法,用于比较2个字符串之间的大小:
字符串比较是按照逐字符进行比较的,如下图源码:
/**
*String字符串源码中的compareTo()方法,
*用于比较2个字符串的大小
*@param anotherString 另外一个字符串
*/
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;}
String的compareTo方法返回的值分两种情形:
1.逐字符比较时,如果一个字符串中的字符和另外一个字符串中的字符相等,则继续比较,直到发现两个字符串中的第一个不相等的2个字符,返回Unicode码的差值(例如:“abe"和"abcd”);
如果在两个字符串中,其中一个字符串是另外一个
2.逐字符进行比较滞后还没有结果,返回两个字符串的长度只差(例如:“abe"和"abcd”)。
举例说明:
package com.bjsxt.sort_bubble;/*** 比较两个字符串的大小* @author WL20180723**/
public class Test {public static void main(String[] args) {String s1 = "abc";String s2 = "abed";String s3 = "abcd";System.out.println(s1.compareTo(s2));System.out.println(s1.compareTo(s3));}}
程序输出结果:
-2
-1
Comparator接口
java.lang包提供了Comparator接口用于对象之间的比较。Comparator接口有很多方法,其中有一个方法叫compare(Object o1, Object o2)是常用比较对象的方法,实现Comparator接口要重写这个方法。接下来我们对冒泡排序进行改进,体会这个接口的使用方法
首先新建一个类实现Comparator接口:
package com.bjsxt.sort_bubble;
import java.util.Comparator;/*** 整数比较类* @author WL20180723**/
public class IntComp implements Comparator<Integer> {/*** 整数比较* o1 > o2 返回 1* o1 == o2 返回 0* o1 < o2 返回 -1*/public int compare(Integer o1, Integer o2) {return o1 > o2 ? 1 : o1 == o2 ? 0 : -1;}
}
接着,将冒泡排序算法封装成一个工具类:
package com.bjsxt.sort_bubble;import java.util.Comparator;/*** 排序工具类* @author WL20180723**/
@SuppressWarnings("unchecked")
public class Utils {/*** 数组排序(升序)* @param <T> 泛型参数* @param arr 要排序的数组* @param com Comparable接口*/public static <T> void sort(Object[] arr, Comparator<T> com) {for(int i = 0; i < arr.length - 1; i++) {for(int j = i + 1; j < arr.length; j++) {if(com.compare((T)arr[i], (T)arr[j]) > 0) {T temp = (T) arr[i];arr[i] = arr[j];arr[j] = temp;}}}}}
这里我们在使用冒泡排序的工具类时,请注意:数组要定义成Integer类型,如果定义成基本类型int类型,会出现类型参数不匹配,从而不能通过编译,因此要格外注意
。
这里大家不禁要问:我们为什么要自己定义一个类去实现JDK提供的Comparator接口呢?
在实际开发中,我们经常要根据具体的业务类型定义各种各样的排序算法,上述样例中按照整数大小排序是一种,就拿实际中经常看的新闻来说,可能按照新闻发生的时间、新闻的重要程度、新闻的评论数等等各种各样复杂的排序要求,从面向对象的角度考虑,新闻发生时间,重要程度,评论次数都可以看作新闻类的属性,而我们恰好就是根据这些属性对自定义的对象进行比较的。所以Java中要比较自定义对象之间的大小或者对包含对象的集合进行比较排序,需要通过比较这些对象的某些属性来确定它们之间的大小关系。此时使用统一的接口,使得代码的结构一目了然,各个排序逻辑之间互相不干扰,大大降低了代码的耦合度,便于后期对系统进行升级和维护。
为了说明使用Comparator接口的好处,我们简单编写一个新闻的排序逻辑,大家自行体会。
假定新闻的排序要求如下:
1.时间降序排列
2.点击量按升序排列
3.新闻标题按降序
首先定义一个新闻类,代码如下:
package com.bjsxt.sort_bubble;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;/*** 新闻条目* @author WL20180723**/
public class NewsItem {/** 新闻标题 **/private String title;/** 新闻发生时间 **/private Date publishTime;/** 新闻点击量 **/private Integer hitCount;public NewsItem() {}public NewsItem(String title, String publishTime, Integer hitCount) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");Date pTime = null;try {pTime = sdf.parse(publishTime);} catch (ParseException e) {System.out.println("时间格式【yyyy-MM-dd】错误:" + publishTime);e.printStackTrace();}this.title = title;this.publishTime = pTime;this.hitCount = hitCount;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public Date getPublishTime() {return publishTime;}public void setPublishTime(Date publishTime) {this.publishTime = publishTime;}public Integer getHitCount() {return hitCount;}public void setHitCount(Integer hitCount) {this.hitCount = hitCount;}public String toString() {return "新闻标题:" + title + "\t新闻发生时间:" + publishTime + "\t点击量:" + hitCount;}}
接着定义实现Comparator接口的实现类:
package com.bjsxt.sort_bubble;import java.util.Comparator;public class NewItemComparable implements Comparator<NewsItem> {/*** 新闻排序* 排序要求:1.时间降序排列* 2.点击量按升序排列* 3.新闻标题按降序*/public int compare(NewsItem n1, NewsItem n2) {int result = 0;//比较结果//1.时间比较//默认是升序,所以加"-"号变成降序result = -n1.getPublishTime().compareTo(n2.getPublishTime());if(result == 0) {//时间相同//2.比较点击量result = n1.getHitCount() - n2.getHitCount();}if(result == 0) {//点击量相同//3.标题result = -n1.getTitle().compareTo(n2.getTitle());}return result;}}
最后进行测试:
package com.bjsxt.sort_bubble;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;/*** 测试新闻排序* @author WL20180723**/
public class TestNews {public static void main(String[] args) {NewsItem n1 = new NewsItem("中国铁路武汉局:8日预计5.5万余名旅客乘火车离汉。", "2020-4-7", 11);NewsItem n2 = new NewsItem("国务院关税税则委员会办公室优化对美加征关税商品,市场化采购排除申报系统。", "2020-4-1", 7);NewsItem n3 = new NewsItem("外交部:中方会继续在南南合作框架内向疫情严重的发展中国家提供力所能及的帮助。", "2020-3-11", 5);NewsItem n4 = new NewsItem("理想汽车CEO李想:疫情影响远超SARS,活下去最重要。", "2020-3-24", 6);NewsItem n5 = new NewsItem("蔚来汽车:3月交付汽车1533辆,今年共交付3838辆汽车。", "2020-3-11", 1);NewsItem n6 = new NewsItem("牧原股份:2020年第一季度净利润同比扭亏为盈。", "2020-3-23", 0);NewsItem n7 = new NewsItem("58名主播被列入黑名单:包括4名电子竞技职业选手。", "2020-4-1", 7);NewsItem n8 = new NewsItem("海底捞涨价6%,你还吃得起吗?", "2020-4-7", 9);List<NewsItem> list = new ArrayList<NewsItem>();list.add(n1);list.add(n2);list.add(n3);list.add(n4);list.add(n5);list.add(n6);list.add(n7);list.add(n8);System.out.println("===============================================================================================");System.out.println("新闻排序前:");System.out.println("===============================================================================================");for(NewsItem n : list) {System.out.println(n);}Collections.sort(list, new NewItemComparable());System.out.println("===============================================================================================");System.out.println("新闻排序后:");System.out.println("===============================================================================================");for(NewsItem n : list) {System.out.println(n);}}}
程序测试输出结果:
===============================================================================================
新闻排序前:
===============================================================================================
新闻标题:中国铁路武汉局:8日预计5.5万余名旅客乘火车离汉。 新闻发生时间:Tue Apr 07 00:00:00 CST 2020 点击量:11
新闻标题:国务院关税税则委员会办公室优化对美加征关税商品,市场化采购排除申报系统。 新闻发生时间:Wed Apr 01 00:00:00 CST 2020 点击量:7
新闻标题:外交部:中方会继续在南南合作框架内向疫情严重的发展中国家提供力所能及的帮助。 新闻发生时间:Wed Mar 11 00:00:00 CST 2020 点击量:5
新闻标题:理想汽车CEO李想:疫情影响远超SARS,活下去最重要。 新闻发生时间:Tue Mar 24 00:00:00 CST 2020 点击量:6
新闻标题:蔚来汽车:3月交付汽车1533辆,今年共交付3838辆汽车。 新闻发生时间:Wed Mar 11 00:00:00 CST 2020 点击量:1
新闻标题:牧原股份:2020年第一季度净利润同比扭亏为盈。 新闻发生时间:Mon Mar 23 00:00:00 CST 2020 点击量:0
新闻标题:58名主播被列入黑名单:包括4名电子竞技职业选手。 新闻发生时间:Wed Apr 01 00:00:00 CST 2020 点击量:7
新闻标题:海底捞涨价6%,你还吃得起吗? 新闻发生时间:Tue Apr 07 00:00:00 CST 2020 点击量:9
===============================================================================================
新闻排序后:
===============================================================================================
新闻标题:海底捞涨价6%,你还吃得起吗? 新闻发生时间:Tue Apr 07 00:00:00 CST 2020 点击量:9
新闻标题:中国铁路武汉局:8日预计5.5万余名旅客乘火车离汉。 新闻发生时间:Tue Apr 07 00:00:00 CST 2020 点击量:11
新闻标题:国务院关税税则委员会办公室优化对美加征关税商品,市场化采购排除申报系统。 新闻发生时间:Wed Apr 01 00:00:00 CST 2020 点击量:7
新闻标题:58名主播被列入黑名单:包括4名电子竞技职业选手。 新闻发生时间:Wed Apr 01 00:00:00 CST 2020 点击量:7
新闻标题:理想汽车CEO李想:疫情影响远超SARS,活下去最重要。 新闻发生时间:Tue Mar 24 00:00:00 CST 2020 点击量:6
新闻标题:牧原股份:2020年第一季度净利润同比扭亏为盈。 新闻发生时间:Mon Mar 23 00:00:00 CST 2020 点击量:0
新闻标题:蔚来汽车:3月交付汽车1533辆,今年共交付3838辆汽车。 新闻发生时间:Wed Mar 11 00:00:00 CST 2020 点击量:1
新闻标题:外交部:中方会继续在南南合作框架内向疫情严重的发展中国家提供力所能及的帮助。 新闻发生时间:Wed Mar 11 00:00:00 CST 2020 点击量:5
对照排序要求,仔细体会新闻排序前和排序后的变化,深刻理解Comparator接口的原理和使用方法。
Comparable接口
java.util包提供了Comparable泛型接口,用于两个对象之间的比较。它定义了唯一一个方法:
package java.lang;
import java.util.*;/**
* @author Josh Bloch
* @since 1.2
*/
public interface Comparable<T> {public int compareTo(T o);
}
凡是实现Comparable接口的类都要实现compareTo(T t)方法。实现Comparable接口的实现类可以通过Collections工具类的sort方法或者Arrays.sort方法进行调用。
上述的新闻的比较方法也可以使用Comparable接口来进行实现。代码如下:
新闻类:
package com.bjsxt.sort_bubble1;import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;public class NewsItem1 implements Comparable<NewsItem1> {/** 新闻标题 **/private String title;/** 新闻发生时间 **/private Date publishTime;/** 新闻点击量 **/private Integer hitCount;public NewsItem1() {}public NewsItem1(String title, String publishTime, Integer hitCount) {SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");Date pTime = null;try {pTime = sdf.parse(publishTime);} catch (ParseException e) {System.out.println("时间格式【yyyy-MM-dd】错误:" + publishTime);e.printStackTrace();}this.title = title;this.publishTime = pTime;this.hitCount = hitCount;}//重写compareTo方法public int compareTo(NewsItem1 o) {int result = 0;//比较结果//1.时间比较//默认是升序,所以加"-"号变成降序result = -this.getPublishTime().compareTo(o.getPublishTime());if(result == 0) {//时间相同//2.比较点击量result = this.getHitCount() - o.getHitCount();}if(result == 0) {//点击量相同//3.标题result = -this.getTitle().compareTo(o.getTitle());}return result;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public Date getPublishTime() {return publishTime;}public void setPublishTime(Date publishTime) {this.publishTime = publishTime;}public Integer getHitCount() {return hitCount;}public void setHitCount(Integer hitCount) {this.hitCount = hitCount;}public String toString() {return "新闻标题:" + title + "\t新闻发生时间:" + publishTime + "\t点击量:" + hitCount;}}
测试类:
package com.bjsxt.sort_bubble1;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public class TestNewsItem1 {public static void main(String[] args) {NewsItem1 n1 = new NewsItem1("中国铁路武汉局:8日预计5.5万余名旅客乘火车离汉。", "2020-4-7", 11);NewsItem1 n2 = new NewsItem1("国务院关税税则委员会办公室优化对美加征关税商品,市场化采购排除申报系统。", "2020-4-1", 7);NewsItem1 n3 = new NewsItem1("外交部:中方会继续在南南合作框架内向疫情严重的发展中国家提供力所能及的帮助。", "2020-3-11", 5);NewsItem1 n4 = new NewsItem1("理想汽车CEO李想:疫情影响远超SARS,活下去最重要。", "2020-3-24", 6);NewsItem1 n5 = new NewsItem1("蔚来汽车:3月交付汽车1533辆,今年共交付3838辆汽车。", "2020-3-11", 1);NewsItem1 n6 = new NewsItem1("牧原股份:2020年第一季度净利润同比扭亏为盈。", "2020-3-23", 0);NewsItem1 n7 = new NewsItem1("58名主播被列入黑名单:包括4名电子竞技职业选手。", "2020-4-1", 7);NewsItem1 n8 = new NewsItem1("海底捞涨价6%,你还吃得起吗?", "2020-4-7", 9);List<NewsItem1> list = new ArrayList<NewsItem1>();list.add(n1);list.add(n2);list.add(n3);list.add(n4);list.add(n5);list.add(n6);list.add(n7);list.add(n8);System.out.println("===============================================================================================");System.out.println("新闻排序前:");System.out.println("===============================================================================================");for(NewsItem1 n : list) {System.out.println(n);}Collections.sort(list);System.out.println("===============================================================================================");System.out.println("新闻排序后:");System.out.println("===============================================================================================");for(NewsItem1 n : list) {System.out.println(n);}}}
测试类运行结果如下:
===============================================================================================
新闻排序前:
===============================================================================================
新闻标题:中国铁路武汉局:8日预计5.5万余名旅客乘火车离汉。 新闻发生时间:Tue Apr 07 00:00:00 CST 2020 点击量:11
新闻标题:国务院关税税则委员会办公室优化对美加征关税商品,市场化采购排除申报系统。 新闻发生时间:Wed Apr 01 00:00:00 CST 2020 点击量:7
新闻标题:外交部:中方会继续在南南合作框架内向疫情严重的发展中国家提供力所能及的帮助。 新闻发生时间:Wed Mar 11 00:00:00 CST 2020 点击量:5
新闻标题:理想汽车CEO李想:疫情影响远超SARS,活下去最重要。 新闻发生时间:Tue Mar 24 00:00:00 CST 2020 点击量:6
新闻标题:蔚来汽车:3月交付汽车1533辆,今年共交付3838辆汽车。 新闻发生时间:Wed Mar 11 00:00:00 CST 2020 点击量:1
新闻标题:牧原股份:2020年第一季度净利润同比扭亏为盈。 新闻发生时间:Mon Mar 23 00:00:00 CST 2020 点击量:0
新闻标题:58名主播被列入黑名单:包括4名电子竞技职业选手。 新闻发生时间:Wed Apr 01 00:00:00 CST 2020 点击量:7
新闻标题:海底捞涨价6%,你还吃得起吗? 新闻发生时间:Tue Apr 07 00:00:00 CST 2020 点击量:9
===============================================================================================
新闻排序后:
===============================================================================================
新闻标题:海底捞涨价6%,你还吃得起吗? 新闻发生时间:Tue Apr 07 00:00:00 CST 2020 点击量:9
新闻标题:中国铁路武汉局:8日预计5.5万余名旅客乘火车离汉。 新闻发生时间:Tue Apr 07 00:00:00 CST 2020 点击量:11
新闻标题:国务院关税税则委员会办公室优化对美加征关税商品,市场化采购排除申报系统。 新闻发生时间:Wed Apr 01 00:00:00 CST 2020 点击量:7
新闻标题:58名主播被列入黑名单:包括4名电子竞技职业选手。 新闻发生时间:Wed Apr 01 00:00:00 CST 2020 点击量:7
新闻标题:理想汽车CEO李想:疫情影响远超SARS,活下去最重要。 新闻发生时间:Tue Mar 24 00:00:00 CST 2020 点击量:6
新闻标题:牧原股份:2020年第一季度净利润同比扭亏为盈。 新闻发生时间:Mon Mar 23 00:00:00 CST 2020 点击量:0
新闻标题:蔚来汽车:3月交付汽车1533辆,今年共交付3838辆汽车。 新闻发生时间:Wed Mar 11 00:00:00 CST 2020 点击量:1
新闻标题:外交部:中方会继续在南南合作框架内向疫情严重的发展中国家提供力所能及的帮助。 新闻发生时间:Wed Mar 11 00:00:00 CST 2020 点击量:5
使用Comparable接口和Comparator接口的效果是一样的。但是也有一些区别:
- 1.Comparator接口位于java.util包下,而Comparable接口位于java.lang包下;
- 2.Comparator接口需要单独新建一个独立的实现类进行比较,Comparable接口直接将比较代码嵌入到进行比较的类的定义中而不需要单独的类去实现Comparable接口,但是嵌入的要进行比较的类要实现Comparable接口。
- 3.如果前期类的设计没有考虑到类的Compare问题而没有实现Comparable接口,后期可以通过Comparator接口来实现比较算法进行排序,并且为了使用不同的排序标准做准备,比如:升序、降序。
- 4.Comparator接口不强制进行自然排序,可以指定排序顺序,而Comparable接口强制进行自然排序。
上面的新闻类的比较就是分别使用Comparator接口和Comparable接口实现的。
TreeSet与Tree Map中,Comparator接口、Comparable接口的使用
TreeSet中使用Comparator接口
自定义Person类:
package com.bjsxt.sort_bubble1;public class Person {/** 姓名 **/private String name;/** 朝代 **/private String dynasty;/** 魅力指数 **/private Integer beauty;public Person(String name, String dynasty, Integer beauty) {this.name = name;this.dynasty = dynasty;this.beauty = beauty;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDynasty() {return dynasty;}public void setDynasty(String dynasty) {this.dynasty = dynasty;}public Integer getBeauty() {return beauty;}public void setBeauty(Integer beauty) {this.beauty = beauty;}public String toString() {return "姓名:" + name + "\t朝代:" + dynasty + "\t魅力指数:" + beauty;}}
测试类:
package com.bjsxt.sort_bubble1;import java.util.Comparator;
import java.util.TreeSet;public class TestPerson {public static void main(String[] args) {Person p1 = new Person("西施", "春秋越国", 92);Person p2 = new Person("王昭君", "汉朝", 98);Person p3 = new Person("貂蝉", "三国", 92);Person p4 = new Person("杨贵妃", "唐代", 96);//依次放入TreeSet容器中,这里使用排序的业务类(匿名内部类)TreeSet<Person> set = new TreeSet<Person>(new Comparator<Person>() {public int compare(Person p1, Person p2) {//排序规则:1.魅力指数升序;2.朝代升序(汉字的比较也是比较Unicode编码的大小)int result = 0;result = p1.getBeauty() - p2.getBeauty();if(result == 0) {result = p1.getDynasty().compareTo(p2.getDynasty());}return result;}});set.add(p1);set.add(p2);set.add(p3);set.add(p4);for(Person p : set) {System.out.println(p);}}}
程序运行结果:
姓名:貂蝉 朝代:三国 魅力指数:92
姓名:西施 朝代:春秋越国 魅力指数:92
姓名:杨贵妃 朝代:唐代 魅力指数:96
姓名:王昭君 朝代:汉朝 魅力指数:98
TreeSet中使用Comparable接口
自定义Person1类:
package com.bjsxt.sort_bubble1;/*** 测试TreeSet中使用Comparator接口* @author WL20180723**/
public class Person1 implements Comparable<Person1> {/** 姓名 **/private String name;/** 朝代 **/private String dynasty;/** 魅力指数 **/private Integer beauty;public Person1(String name, String dynasty, Integer beauty) {this.name = name;this.dynasty = dynasty;this.beauty = beauty;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getDynasty() {return dynasty;}public void setDynasty(String dynasty) {this.dynasty = dynasty;}public Integer getBeauty() {return beauty;}public void setBeauty(Integer beauty) {this.beauty = beauty;}public String toString() {return "姓名:" + name + "\t朝代:" + dynasty + "\t魅力指数:" + beauty;}//重写compareTo方法public int compareTo(Person1 p1) {//排序规则:1.魅力指数升序;2.朝代升序(汉字的比较也是比较Unicode编码的大小)int result = 0;result = this.getBeauty() - p1.getBeauty();if(result == 0) {result = this.getDynasty().compareTo(p1.getDynasty());}return result;}}
测试类TestPerson1:
package com.bjsxt.sort_bubble1;import java.util.TreeSet;/*** 测试TreeSet中使用Comparable接口* @author WL20180723**/
public class TestPerson1 {public static void main(String[] args) {Person1 p1 = new Person1("西施", "春秋越国", 92);Person1 p2 = new Person1("王昭君", "汉朝", 98);Person1 p3 = new Person1("貂蝉", "三国", 92);Person1 p4 = new Person1("杨贵妃", "唐代", 96);TreeSet<Person1> set = new TreeSet<Person1>();set.add(p1);set.add(p2);set.add(p3);set.add(p4);for(Person1 p : set) {System.out.println(p);}}}
程序输出结果:
姓名:貂蝉 朝代:三国 魅力指数:92
姓名:西施 朝代:春秋越国 魅力指数:92
姓名:杨贵妃 朝代:唐代 魅力指数:96
姓名:王昭君 朝代:汉朝 魅力指数:98
TreeMap中使用Comparator接口
自定义类还是Person类。测试类TestPerson2:
package com.bjsxt.sort_bubble1;import java.util.Comparator;
import java.util.TreeMap;/*** 测试TreeMap中使用Comparator接口* @author WL20180723**/
public class TestPerson2 {public static void main(String[] args) {Person p1 = new Person("西施", "春秋越国", 92);Person p2 = new Person("王昭君", "汉朝", 98);Person p3 = new Person("貂蝉", "三国", 92);Person p4 = new Person("杨贵妃", "唐代", 96);//依次放入TreeMap容器中,这里使用排序的业务类(匿名内部类)TreeMap<Person, String> map = new TreeMap<Person, String>(new Comparator<Person>() {public int compare(Person p1, Person p2) {//排序规则:1.魅力指数升序;2.朝代升序(汉字的比较也是比较Unicode编码的大小)int result = 0;result = p1.getBeauty() - p2.getBeauty();if(result == 0) {result = p1.getDynasty().compareTo(p2.getDynasty());}return result;}});map.put(p1, "古代四大美人");map.put(p2, "古代四大美人");map.put(p3, "古代四大美人");map.put(p4, "古代四大美人");//查看键for(Person p : map.keySet()) {System.out.println(p);}}}
程序输出结果:
姓名:貂蝉 朝代:三国 魅力指数:92
姓名:西施 朝代:春秋越国 魅力指数:92
姓名:杨贵妃 朝代:唐代 魅力指数:96
姓名:王昭君 朝代:汉朝 魅力指数:98
TreeMap中使用Comparable接口
自定义类还是Person1。自定义测试类TestPerson3:
package com.bjsxt.sort_bubble1;import java.util.TreeMap;/*** 测试TreeMap中使用Comparable接口* @author WL20180723**/
public class TestPerson3 {public static void main(String[] args) {Person1 p1 = new Person1("西施", "春秋越国", 92);Person1 p2 = new Person1("王昭君", "汉朝", 98);Person1 p3 = new Person1("貂蝉", "三国", 92);Person1 p4 = new Person1("杨贵妃", "唐代", 96);TreeMap<Person1, String> map = new TreeMap<Person1, String>();map.put(p1, "古代四大美人");map.put(p2, "古代四大美人");map.put(p3, "古代四大美人");map.put(p4, "古代四大美人");for(Person1 p : map.keySet()) {System.out.println(p);}}}
程序运行结果:
姓名:貂蝉 朝代:三国 魅力指数:92
姓名:西施 朝代:春秋越国 魅力指数:92
姓名:杨贵妃 朝代:唐代 魅力指数:96
姓名:王昭君 朝代:汉朝 魅力指数:98
Java中的冒泡排序,Comparator接口和Comparable接口的简单使用相关推荐
- java:对象比较的三种方法equals()方法,Comparator接口,Comparable接口
一.java中对象的比较 方法: 1.==和equals方法(只能比较是否相等,无法比较大小) 2.hashCode()和equals()方法(可比大小,或用来排序) 3.Comparator接口和C ...
- Java中常用的类,包,接口
Java中常用的类,包,接口 包名 说明 java.lang 该包提供了Java编程的基础类,例如 Object.Math.String.StringBuffer.System.Thread等,不使用 ...
- JAVA中常量使用常量类或者常量接口还是使用枚举,错误代码和中文可变信息的枚举实现
文章目录 关于"JAVA中常量使用常量类或者常量接口还是使用枚举",已有定论-使用枚举,原因就不再展开了. 借助java枚举,可以在定义错误名称和代码的同时,定义中文描述信息,但是 ...
- java arraylist comparable_Java 两种ArrayList集合自定义对象属性排序,Comparator接口 或 Comparable接口...
1,Comparator接口 -- 重写Comparator public class User { private String id; private String name; public Us ...
- comparator接口与Comparable接口的区别
Comparable & Comparator 都是用来实现集合中元素的比较.排序的,只是 Comparable 是在集合内部定义的方法实现的排序,Comparator 是在集合外部实现的排序 ...
- java中sort函数comparator的使用_Comparator 与排序
Java 排序 Java 中经常需要对一个列表进行排序,列表中可能是基本数据类型,也可能是自定义对象,对于自定义对象的排序我们可能只想按照其某个属性排序,甚至多种条件组合对其排序,这些都可以借助于 C ...
- Java中的Map【二】SortedMap接口
所使用的jdk版本为1.8版本,先看一下SortedMap在JDK中Map的UML类图中的位置: 2.1.2 SortedMap接口 SortedMap<K,V>继承Map ...
- java中接口适配器实现,12.1.8 Java中的应用-AWT事件适配器(接口的适配器模式)...
12.1.8 Java中的应用-AWT事件适配器(接口的适配器模式) 从以上的学习我们已经了解到,基于接口的适配器模式是采用抽象化接口的方式,来达到节省接口函数的目的,这一特性特别适合于Java A ...
- Java中继承thread类与实现Runnable接口的区别
Java中线程的创建有两种方式: 1. 通过继承Thread类,重写Thread的run()方法,将线程运行的逻辑放在其中 2. 通过实现Runnable接口,实例化Thread类 在实际应用中, ...
最新文章
- 计算机后期剪辑专业是学什么,【答疑】学后期剪辑用什么电脑比较好?有什么电脑配置要求? - 视频教程线上学...
- 二、SpringMVC的常用注解——1-@Controller
- 5.7 程序示例--基于 SMO 的 SVM 模型-机器学习笔记-斯坦福吴恩达教授
- hadoop启动报错:localhost: ssh: Could not resolve hostname localhost
- win7系统服务器环境配置,windows7系统安装与配置Tomcat服务器环境
- select简易的二级联动
- cloudflare 关于tls 检测,发送未知message type字节
- 详解 undefined 与 null 的区别
- readonly属性
- 完全激活office2007
- 罗格斯的计算机科学,罗格斯大学计算机
- 基二FFT时间抽取和频域抽取算法
- 管理Linux 系统的用户与用户组
- 布袋除尘器类毕业论文文献有哪些?
- 学习GestureDetectorCompat,实现卡片左右滑动消失效果
- 浙江大学python程序设计(陈春晖、翁恺、季江民)习题答案
- (转)Linux 一句话精彩问答
- 北京精雕自定义机床模型仿真
- 一个让我用得很爽的个性导航h2w1.com
- Java Log4j和Log4j2的区别
热门文章
- 使用Scikit-learn开启机器学习之旅
- java流意外结束_SyntaxError:输入节点js的意外结束
- 将不同数据来源的ggplot图绘制到同一张图中,并添加统一的图例
- 采用非常规方法(非gprecoverseg) 恢复greenplum数据库
- 常用10个Excel快捷键,提高工作效率
- 计算机一级怎么截图保存到桌面,电脑怎么截图?截屏?(四种方法),划重点了...
- cmake简洁教程 - 第五篇
- 求树的最大宽度(层次遍历法)
- Python原生服务端签名生成请求订单信息「orderString」
- python判断某一天是一年中的第几天