“排序”的实体类都实现了java.lang.Comparable
接口。
Comparable接口中只有一个方法:
public int compareTo(Object obj);
该方法:
返回0,表示this ==obj
返回正数,表示this>obj
返回负数,表示this<obj
实现了Comparable接口的类通过实现compareTo方法从而确定该类对象的排序方式。
一、引用数据类型比较(内置数据)
package innerType;
/**
* 引用数据类型
* 1.内置类
* 整数、小数Integer Float Double 直接比较数据类型的大小
* 2.字符:比较的Unicode码之差
* 3.字符串
* 1)如果其中一个是另一个起始开始的子串,返回长度之差
* 2)否则返回第一个不相等的unicode码之差
* 4.java.util.Date 根据日期的长整型比较
*/
@SuppressWarnings("all")
public class Demo01 {
public static void main(String[] args) {
Integer a;//根据基本数据类型大小
Character ch;//根据Unicode编码顺序
String str="abc";
String str2 = "abcdegfdsf32";
System.out.println(str.compareTo(str2));
String str3="abcde";
String str4 = "abd";
System.out.println(str3.compareTo(str4));
}
}
运行结果:
-9
-1
1、实体类 java.lang.Comparable+compareTo
package innerType;
import java.util.Arrays;
import java.util.Date;
/**
* 引用类型冒泡排序
* @author liguodong
*/
@SuppressWarnings("all")
public class Demo02 {
public static void main(String[] args) {
String[] str = {"a","abd","abcd","def"};
//从小到大排序
int len = str.length;
BubbleSortThird(str,len);
Date[] date = new Date[3];
date[0] = new Date();
date[1] = new Date(System.currentTimeMillis()-1000*60*60);
date[2] = new Date(System.currentTimeMillis()+1000*60*60);
BubbleSortThird(date,date.length);
}
private static void BubbleSortThird(String[] arr,int len)
{
boolean sorted = true;
for(int j=0;j<len-1;j++)
{
sorted = true;
for(int i=0;i<len-1-j;i++)
{
/**
* String引用数据类型,需要使用compareTo进行比较。
*/
if(((Comparable)arr[i]).compareTo(arr[i+1])>0)
{
String temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
sorted = false;
}
}
if(sorted)
{
break;
}
}
System.out.println(Arrays.toString(arr));
}
private static void BubbleSortThird(Date[] arr,int len)
{
boolean sorted = true;
for(int j=0;j<len-1;j++)
{
sorted = true;
for(int i=0;i<len-1-j;i++)
{
/**
* Date引用数据类型,需要使用compareTo进行比较。
*/
if(((Comparable)arr[i]).compareTo(arr[i+1])>0)
{
Date temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
sorted = false;
}
}
if(sorted)
{
break;
}
}
System.out.println(Arrays.toString(arr));
}
}
运行结果:
[a, abcd, abd, def]
[Sun May 17 10:23:48 CST 2015, Sun May 17 11:23:48 CST 2015, Sun May 17 12:23:48 CST 2015]
package innerType;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
/**
* 工具类
* @author liguodong
*
*/
@SuppressWarnings("all")
public class Utils01 {
public static void BubbleSort(Object[] arr)
{
boolean sorted = true;
int len = arr.length;
for(int j=0;j<len-1;j++)
{
sorted = true;
for(int i=0;i<len-1-j;i++)
{
/**
* 引用数据类型,需要使用compareTo进行比较。
*/
if(((Comparable)arr[i]).compareTo(arr[i+1])>0)
{
Object temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
sorted = false;
}
}
if(sorted)
{
break;
}
}
System.out.println(Arrays.toString(arr));
}
/**
* 数组排序<泛型>
*/
public static<T extends Comparable<T>> void BubbleSort(T[] arr)
{
boolean sorted = true;
int len = arr.length;
for(int j=0;j<len-1;j++)
{
sorted = true;
for(int i=0;i<len-1-j;i++)
{
if(((Comparable)arr[i]).compareTo(arr[i+1])>0)
{
T temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
sorted = false;
}
}
if(sorted)
{
break;
}
}
System.out.println(Arrays.toString(arr));
}
/**
* 容器排序<使用泛型>
*/
public static <T extends Comparable<T>> void BubbleSort(List<T> list)
{
//第一步:转成数组
Object [] arr = list.toArray();
BubbleSort(arr);
//第二步:改变容器中对应的值
for(int i=0; i<arr.length; i++)
{
list.set(i, (T)(arr[i]));
}
}
/**
* list的排序+比较器
* @param list
* @param com
*/
public static <T> void BubbleSort(List<T> list,Comparator<T> com)
{
//第一步:转成数组
Object [] arr = list.toArray();
Sort( arr,com);
//第二步:改变容器中对应的值
for(int i=0; i<arr.length; i++)
{
list.set(i, (T)(arr[i]));
}
}
/**
* 数组的排序(降序)+Comparator接口
* @param arr
*/
public static void Sort(Object[] arr,Comparator com)
{
boolean sorted = true;
int len = arr.length;
for(int j=0;j<len-1;j++)
{
sorted = true;
for(int i=0;i<len-1-j;i++)
{
if(com.compare(arr[i], arr[i+1])<0)
{
Object temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
sorted = false;
}
}
if(sorted){
break;
}
}
System.out.println(Arrays.toString(arr));
}
}
package innerType;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
*
* @author liguodong
*
*/
public class Demo03 {
public static void main(String[] args) {
System.out.println("------数组排序----------");
/**
* 1、数组排序
*/
String[] str = {"a","abd","abcd","def"};
//从小到大排序
Utils01.BubbleSort(str);
Date[] date = new Date[3];
date[0] = new Date();
date[1] = new Date(System.currentTimeMillis()-1000*60*60);
date[2] = new Date(System.currentTimeMillis()+1000*60*60);
Utils01.BubbleSort(date);
/**
* 2、容器排序
*/
//存放到容器中
System.out.println("------容器排序----------");
List<String> list = new ArrayList<>();
list.add("a");
list.add("abcd");
list.add("abdd");
list.add("def");
Utils01.BubbleSort(list);
}
}
运行结果:
------数组排序----------
[a, abcd, abd, def]
[Sun May 17 10:52:53 CST 2015, Sun May 17 11:52:53 CST 2015, Sun May 17 12:52:53 CST 2015]
------容器排序----------
[a, abcd, abdd, def]
2、业务排序类java.util.Comparator+compare
思考:很多排序规则,如淘宝商品价格点击量名称等等,只有字节码没有源码,怎么办?
提供排序的比较器,业务比较器
实现java.util.Comparator
接口,
重写public int compare(T o1,T o2);
作用:
解藕:独立于实体类
方便:便于应对各种排序规则
package innerType;
public class StringComp implements java.util.Comparator<String>{
/**
* 按长度比较大小
* 正> 负< 零=
*/
public int compare(String o1,String o2)
{
int len1 = o1.length();
int len2 = o2.length();
return len1-len2;
}
}
package innerType;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
@SuppressWarnings("all")
public class Utils02 {
/**
* 数组的排序(降序)+Comparator接口
* @param arr
*/
public static void BubbleSort(Object[] arr,Comparator com)
{
boolean sorted = true;
int len = arr.length;
for(int j=0;j<len-1;j++)
{
sorted = true;
for(int i=0;i<len-1-j;i++)
{
if(com.compare(arr[i], arr[i+1])<0)
{
Object temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
sorted = false;
}
}
if(sorted){
break;
}
}
System.out.println(Arrays.toString(arr));
}
/**
* list的排序+比较器
* @param list
* @param com
*/
public static <T> void BubbleSort(List<T> list,Comparator<T> com)
{
//第一步:转成数组
Object [] arr = list.toArray();
BubbleSort(arr,com);
//第二步:改变容器中对应的值
for(int i=0; i<arr.length; i++)
{
list.set(i, (T)(arr[i]));
}
}
}
package innerType;
import java.util.ArrayList;
import java.util.List;
public class Demo04 {
public static void main(String[] args) {
/**
* 使用Compatator数组排序
*/
String[] arr = new String[] {"a","abcd","abc","def"};
Utils02.BubbleSort(arr,new StringComp());
List<String> list = new ArrayList<>();
list.add("a");
list.add("abcd");
list.add("abbd");
list.add("def");
Utils02.BubbleSort(list,new StringComp());
}
}
运行结果:
[abcd, abc, def, a]
[abcd, abbd, def, a]
3、工具类Collections
工具类Collections,提供了大量便于处理的容器的方法。
排序方法:
public static <T extends Comparable<? super T>> void sort(List<T> list)
void sort(sort(List<T> list)
public static <T> void sort(List<T> list,Comparator<? super T> com)
package innerType;
public class StringComp implements java.util.Comparator<String>{
/**
* 按长度比较大小
* 正> 负< 零=
*/
public int compare(String o1,String o2)
{
int len1 = o1.length();
int len2 = o2.length();
return len1-len2;
}
}
package innerType;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Demo05 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("a");
list.add("gdsf");
list.add("fdsf");
list.add("vcxvfd");
System.out.println("方式一");
Collections.sort(list);
System.out.println(list);
System.out.println("方式二");
Collections.sort(list,new StringComp());
System.out.println(list);
}
}
二、引用数据类型比较(自定义数据)
新闻排序:
时间、点击量、标题
1、实体类 实现java.lang.Comparable接口+重写compareTo方法
package reference;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 实体类
* @author liguodong
*/
public class NewsItem implements java.lang.Comparable<NewsItem>{
private String title; //标题
private int hits; //点击量
private Date pubTime; //时间
public NewsItem(String title, int hits, Date pubTime) {
super();
this.title = title;
this.hits = hits;
this.pubTime = pubTime;
}
public NewsItem() {
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public int getHits() {
return hits;
}
public void setHits(int hits) {
this.hits = hits;
}
public Date getPubTime() {
return pubTime;
}
public void setPubTime(Date pubTime) {
this.pubTime = pubTime;
}
/**
* 业务:先按时间降序,再按点击量升序+标题降序
*/
@Override
public int compareTo(NewsItem o) {
int result = 0;
//比较时间
result = -this.pubTime.compareTo(o.pubTime);//降序
if(0==result)//时间相同
{
//点击量
result = this.hits-o.hits;//升序
if(0==result)//点击量相同
{
//标题降序
result = -this.title.compareTo(o.title);
}
}
return result;
}
public String toString()
{
StringBuilder sb = new StringBuilder();
sb.append("\n标题:").append(this.title);
sb.append(",时间:").append(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.pubTime));
sb.append(",点击量:").append(this.hits);
return sb.toString();
}
}
package reference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
//使用Collections
public class Demo01 {
public static void main(String[] args) {
List<NewsItem> news = new ArrayList<>();
news.add(new NewsItem("中国人民,生活越来越幸福了",100,new Date()));
news.add(new NewsItem("国外人民生活在水深火热中",30,new Date(System.currentTimeMillis()+1000*60*60)));
news.add(new NewsItem("台湾回归,举国同庆", 50, new Date(System.currentTimeMillis()-2000*60*60)));
System.out.println("排序前:\n"+news);
//排序
Collections.sort(news);//默认是升序,想降序自己改
System.out.println("排序后:\n"+news);
}
}
运行结果:
排序前:
[
标题:中国人民,生活越来越幸福了,时间:2015-05-17 16:03:35,点击量:100,
标题:国外人民生活在水深火热中,时间:2015-05-17 17:03:35,点击量:30,
标题:台湾回归,举国同庆,时间:2015-05-17 14:03:35,点击量:50]
排序后:
[
标题:国外人民生活在水深火热中,时间:2015-05-17 17:03:35,点击量:30,
标题:中国人民,生活越来越幸福了,时间:2015-05-17 16:03:35,点击量:100,
标题:台湾回归,举国同庆,时间:2015-05-17 14:03:35,点击量:50]
2、业务排序类 实现java.util.Comparator+重写compare方法
package reference;
/**
* 实体类
*/
public class Goods {
private String name;//商品名称
private int price;//价格
private int fav;//收藏量
public Goods(String name, int price, int fav) {
super();
this.name = name;
this.price = price;
this.fav = fav;
}
public Goods() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public int getFav() {
return fav;
}
public void setFav(int fav) {
this.fav = fav;
}
@Override
public String toString() {
return "\n商品名:"+name+" 收藏量:"+this.fav+" 价格:"+this.price;
}
}
package reference;
/**
* 按收藏量排序(升序)
*/
public class GoodsFavComp implements java.util.Comparator<Goods>{
@Override
public int compare(Goods o1, Goods o2) {
return o1.getFav()-o2.getFav();
}
}
package reference;
/**
* 按照价格排序的业务类(降序)
*/
public class GoodsPriceComp implements java.util.Comparator<Goods>{
public int compare(Goods o1,Goods o2)
{
return -(o1.getPrice()-o2.getPrice()>0?1:(o1.getPrice()==o2.getPrice()?0:-1));
}
}
package reference;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class Demo02 {
public static void main(String[] args) {
List<Goods> list = new ArrayList<>();
list.add(new Goods("彩色祥云",1000,2000));
list.add(new Goods("天使嫁衣",1050,1000));
list.add(new Goods("坠痕流星",103,500));
System.out.println("排序前:\n"+list);
//Collections.sort(list,new GoodPriceComp());
Collections.sort(list,new GoodsFavComp());
System.out.println("排序后:\n"+list);
}
}
运行结果:
排序前:
[
商品名:彩色祥云 收藏量2000 价格:1000,
商品名:天使嫁衣 收藏量1000 价格:1050,
商品名:坠痕流星 收藏量500 价格:103]
排序后:
[
商品名:坠痕流星 收藏量500 价格:103,
商品名:天使嫁衣 收藏量1000 价格:1050,
商品名:彩色祥云 收藏量2000 价格:1000]
三、排序容器
TreeMap:确保key可以排序或者提供比较器
确保key可以排序
提供key比较器public TreeMap(Comparator<? super K> comparator)
TreeSet:
确保元素实体可以排序
排序比较器public TreeSet(Comparator<? super E> comparator)
1、TreeSet数据元素可以排序且不可重复
对比:Set接口:HashSet,元素必须重写hashCode与equals方法。
去重:比较等于0,即重复。
1)、实体类 元素可以排序 实现java.lang.Comparable接口+重写compareTo方法
2)、业务排序类 实现java.util.Comparator+重写compare方法
package SortCollection;
public class Person {
private final String name;
private int handsome;
public Person() {
name = null;
}
public Person(String name, int handsome) {
super();
this.name = name;
this.handsome = handsome;
}
public String getName() {
return name;
}
/*public void setName(String name) {
this.name = name;
}*/
public int getHandsome() {
return handsome;
}
public void setHandsome(int handsome) {
this.handsome = handsome;
}
@Override
public String toString() {
return "\n姓名:"+this.name+" 帅气指数:"+this.handsome;
}
}
package SortCollection;
import java.util.TreeSet;
/**
* 解耦方式实现业务排序类
*/
public class Demo01 {
public static void main(String[] args) {
Person p1 = new Person("一",100);
Person p2 = new Person("二",1000);
Person p3 = new Person("三",1200);
Person p4 = new Person("四",50);
//依次存放到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);
persons.add(p4);
System.out.println(persons);
//改变数据 数据不会更改原来的顺序,并且数据可能重复,修改数据不会有任何的顺序变化。
System.out.println("修改数据之后:");
p3.setHandsome(-100);
System.out.println(persons);
}
}
运行结果:
[
姓名:四 帅气指数:50,
姓名:一 帅气指数:100,
姓名:二 帅气指数:1000,
姓名:三 帅气指数:1200]
修改数据之后:
[
姓名:四 帅气指数:50,
姓名:一 帅气指数:100,
姓名:二 帅气指数:1000,
姓名:三 帅气指数:-100]
**注意:**TreeSet 在添加数据时排序,修改数据不会有任何的顺序变化,不要修改数据,否则可能引起重复。
确保数据不能修改,可以在属性前面添加final。
package SortCollection;
/**
* 实体类实现Compatable接口
*/
public class Worker implements java.lang.Comparable<Worker>{
private final String name;
private final double salary;
public Worker() {
name = null;
salary = 0;
}
public Worker(String name, double salary) {
super();
this.name = name;
this.salary = salary;
}
public String getName() {
return name;
}
/*public void setName(String name) {
this.name = name;
}*/
public double getSalary() {
return salary;
}
/*public void setSalary(double salary) {
this.salary = salary;
}*/
@Override
public int compareTo(Worker o) {
return this.salary>o.salary?1:((this.salary==o.salary)?0:-1);//升序
}
@Override
public String toString() {
return "\n工种:"+this.name+" 工资:"+this.salary;
}
}
package SortCollection;
import java.util.TreeSet;
public class Demo02 {
public static void main(String[] args) {
Worker w1 = new Worker("垃圾回收员",12000);
Worker w2 = new Worker("农民工",10000);
Worker w3 = new Worker("程序员",11000);
TreeSet<Worker> empoyee = new TreeSet<Worker>();
empoyee.add(w1);
empoyee.add(w2);
empoyee.add(w3);
System.out.println(empoyee);
}
}
运行结果:
[
工种:农民工 工资:10000.0,
工种:程序员 工资:11000.0,
工种:垃圾回收员 工资:12000.0]
2、TreeMap
package SortCollection;
import java.util.Set;
import java.util.TreeMap;
public class Demo03 {
// Dummy value to associate with an Object in the backing Map
private static final Object PRESENT = new Object();
public static void main(String[] args) {
Person p1 = new Person("一",100);
Person p2 = new Person("二",1000);
Person p3 = new Person("三",1200);
Person p4 = new Person("四",50);
TreeMap<Person, Object> map = new TreeMap<>(
new java.util.Comparator<Person>()
{
@Override
public int compare(Person o1, Person o2) {
return o1.getHandsome()-o2.getHandsome();
}
}
);
map.put(p1, PRESENT);
map.put(p2, PRESENT);
map.put(p3, PRESENT);
map.put(p4, PRESENT);
//查看键
Set<Person> persons = map.keySet();
System.out.println(persons);
}
}
运行结果:
[
姓名:四 帅气指数:50,
姓名:一 帅气指数:100,
姓名:二 帅气指数:1000,
姓名:三 帅气指数:1200]
package SortCollection;
import java.util.TreeMap;
public class Demo04 {
public static void main(String[] args) {
Worker w1 = new Worker("垃圾回收员",12000);
Worker w2 = new Worker("农民工",10000);
Worker w3 = new Worker("程序员",11000);
TreeMap<Worker,String> empoyee = new TreeMap<>();
empoyee.put(w1,"scgalgd");
empoyee.put(w2,"scgalgd");
empoyee.put(w3,"scgalgd");
System.out.println(empoyee.keySet());
}
}
运行结果:
[
工种:农民工 工资:10000.0,
工种:程序员 工资:11000.0,
工种:垃圾回收员 工资:12000.0]
四、Collections 工具类
package Collections;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
* 1.binarySearch 二分搜索法搜索指定列表,以获得指定对象,必须要容器有序
* 2.sort(List<T> list)
* sort(List<T> list,Comparator<? super T> c)
* 3.reverse(List<?> list)
* 4.shuffle(List<?> list)洗牌
* 5.swap(List<?> list, int i ,int j)
*/
public class Demo01 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
//shuffer洗牌 模拟斗地主
for(int i=0;i<54;i++)
{
list.add(i);
}
//洗牌
Collections.shuffle(list);
//依次发牌
List<Integer> p1 = new ArrayList<Integer>();
List<Integer> p2 = new ArrayList<Integer>();
List<Integer> p3 = new ArrayList<Integer>();
List<Integer> last = new ArrayList<>();
for(int i=0;i<51;i+=3)
{
p1.add(list.get(i));
p2.add(list.get(i+1));
p3.add(list.get(i+2));
}
last.add(list.get(51));
last.add(list.get(52));
last.add(list.get(53));
System.out.println("第一个人:"+p1);
System.out.println("第二个人:"+p2);
System.out.println("第三个人:"+p3);
System.out.println("底牌为:"+last);
}
//测试反转
public static void reverse()
{
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
System.out.println(list);
Collections.reverse(list);
System.out.println("反转之后:"+list);
}
}