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
  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值