一、基本类型排序
1、自定义实现冒泡排序
import java.util.Arrays;
/**
* 冒泡排序
*/
public class BubbleSort {
public static void sort(int[] arr){
int len = arr.length;
boolean sort = true;
for(int j=0;j<len-1;j++){
//总共需要比较的趟数
System.out.println("第"+(j+1)+"趟");
sort = true; // 假定有序
for(int i=0;i<len-1-j;i++){
//每趟需要比较的次数
int temp;
if(arr[i]>arr[i+1]){
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
sort = false; //如果发生交换,则说明还是无序
}
System.out.println("第"+(i+1)+"次:"+Arrays.toString(arr));
}
if(sort){
//如果有序,则不做下一趟的比较
break;
}
}
}
public static void main(String[] args) {
int[] arr = {
2,3,9,8,7};
sort(arr);
System.out.println("最终结果:"+Arrays.toString(arr));
}
}
2、找出一组数中最大值
(1)冒泡排序法
/**
* 冒泡排序求最大值
*/
public class BubbleSort {
public static int findMax(int[] arr){
for(int i=0;i<arr.length-1;i++){
int temp;
if(arr[i]>arr[i+1]){
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
return arr[arr.length-1];
}
public static void main(String[] args) {
int[] arr = {
1,3,8,9,4,5,8};
int result = findMax(arr);
System.out.println("最大值为:"+result);
}
}
(2)设置一个最大值,挨个跟数组中的值做比较
public class FindMax {
public static void main(String[] args) {
int[] arr = {
1,3,8,9,4,5,8};
int max = arr[0];
for(int i=0;i<arr.length;i++){
if(max-arr[i]<0){
max = arr[i];
}
}
System.out.println("最大值为:"+max);
}
}
二、引用类型的排序策略
1、Comparable接口
实体类实现java.lang.Comparable接口,重写compareTo()方法
(1)compareTo()方法:比较同类型的两个对象
a、比较字符串(String)类型对象:str1.compareTo(str2),按照最短的字符串长度,逐个比较str1和str2对应位置的字符,若对应位置的字符相等,则比较下一个字符,若对应位置的字符不相等,则返回str1该位置字符 - str2该位置字符的差值,如果全部相等,则返回str1长度 - str2长度的差值
b、比较时间类型(Date)对象:date1.compareTo(date2),如果date1毫秒数 > date2毫秒数返回1,若 < 返回 -1,若 = 返回 0
c、比较整数型(Integer)对象:int1.compareTo(int2),如果int1 > int2返回1,若 < 返回 -1,若 = 返回0
import java.util.Date;
/**
* 内置类比较大小
*/
public class TestComparable {
public static void main(String[] args) {
String str1 = "abc";
String str2 = "f";
int result = str1.compareTo(str2);
System.out.println(result);
Date date1 = new Date();
Date date2 = new Date(System.currentTimeMillis()-1000*60*60);
result = date1.compareTo(date2);
System.out.println(result);
Integer lnter1 = 300;
Integer lnter2 = 500;
result = lnter1.compareTo(lnter2);
System.out.println(result);
}
}
(2)内置类排序:常用内置类里已经实现了Comparable接口,重写了compareTo()方法,如String,Date、Integer等
import java.util.Comparator;
import java.util.List;
/**
* 使用compareTo()排序
*/
public class SortUtil {
//数组排序(使用泛型方法) Comparable排序类
public <T extends Comparable<T>> void arrSort(T[] arr){
int len = arr.length;
boolean sort = true;
for(int j=0;j<len-1;j++){
sort = true;
for(int i=0;i<len-1-j;i++){
T temp;
if(((Comparable)arr[i]).compareTo(arr[i+1])<0){
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
sort = false;
}
}
if(sort){
break;
}
}
}
//数组排序(降序排列) Comparable排序类
public void arrSort(Object[] arr){
int len = arr.length;
boolean sort = true;
for(int j=0;j<len-1;j++){
sort = true;
for(int i=0;i<len-1-j;i++){
Object temp;
if(((Comparable)arr[i]).compareTo(arr[i+1])<0){
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
sort = false;
}
}
if(sort){
break;
}
}
}
public static void main(String[] args) {
SortUtil util = new SortUtil();
String[] str = {
"cdfee","acda","efg","a"};
util.arrSort(str);
System.out.println(Arrays.toString(str));
}
(3)自定义实体类,实现Compareble接口
import java.util.Date;
/**
* 新闻类,按照点击量降序、发布时间降序、标题升序;实现Compareble接口
*/
public class NewsItem implements Comparable<NewsItem>{
private int hits; //点击量
private Date pubDate; //发布时间
private String title; //标题
public NewsItem(){
}
public NewsItem(int hits, Date pubDate, String title) {
super();
this.hits = hits;
this.pubDate = pubDate;
this.title = title;
}
public int getHits() {
return hits;
}
public void setHits(int hits) {
this.hits = hits;
}
public Date getPubDate() {
return pubDate;
}
public void setPubDate(Date pubDate) {
this.pubDate = pubDate;
}
public String getTitle() {
return title;
}
public void setTitile(String title) {
this.title = title;
}
@Override
public int compareTo(NewsItem o) {
//重写compareTo()
int hits2 = o.hits;
Date pubDate2 = o.pubDate;
String title2 = o.title;
int result = hits-hits2;
if(result==0){
result = pubDate.compareTo(pubDate2);
if(result==0){
result = title.compareTo(title2);
if(result!=0){
return -result;
}
}
}
return result;
}
}
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 对新闻对象进行排序
*/
public class NewsSortTest {
//容器排序(转换成数组比较,使用泛型),使用Comparable类
public static <T extends Comparable<T>> void listSort(List<T> list){
Object[] arr = list.toArray();
arrSort(arr);
for(int i=0;i<arr.length;i++){
list.set(i, (T) arr[i]);
}
}
//数组排序,使用Comparable类
public static void arrSort(Object[] arr){
int len = arr.length;
boolean sort = true;
for(int j=0;j<len-1;j++){
sort = true;
for(int i=0;i<len-1-j;i++){
Object temp;
if(((Comparable)arr[i]).compareTo(arr[i+1])<0){
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
sort = false;
}
}
if(sort){
break;
}
}
}
public static void main(String[] args){
List<NewsItem> list = new ArrayList<NewsItem>();
list.add(new NewsItem(5000,new Date(),"这是一个自定义类比较大小测试"));
list.add(new NewsItem(1000,new Date(System.currentTimeMillis()-1000*60*60),"测试测试"));
list.add(new NewsItem(5000,new Date(),"我是自定义类"));
list.add(new NewsItem(1000,new Date(),"这是一个自定义类比较大小测试"));
list.add(new NewsItem(100,new Date(),"这是一个自定义类比较大小测试"));
listSort(list);
NewsItem item = new NewsItem();
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for(int i=0;i<list.size();i++){
item = list.get(i);
System.out.println("标题:"+item.getTitle() +"\t"+"点击量:"+item.getHits()+"\t"+"发布时间:"+format.format(item.getPubDate()));
}
}
}
2、Comparator接口(比较器)
业务排序类实现java.util.Comparator接口,重写compare()方法
优点:a、解耦:与实体类分离 2、方便:应对多变的排序规则(如果有不同的排序规则再写一个业务排序类就可以了)
(1)自定义类实现Comparator接口
此处依然定义新闻类,但是与排序类是分离的,实现效果与上面相同
import java.util.Date;
/**
* 新闻类
*/
public class NewsItem2{
private int hits; //点击量
private Date pubDate; //发布时间
private String title; //标题
public NewsItem2(){
}
public NewsItem2(int hits, Date pubDate, String title) {
super();
this.hits = hits;
this.pubDate = pubDate;
this.title = title;
}
public int getHits() {
return hits;
}
public void setHits(int hits) {
this.hits = hits;
}
public Date getPubDate() {
return pubDate;
}
public void setPubDate(Date pubDate) {
this.pubDate = pubDate;
}
public String getTitle() {
return title;
}
public void setTitile(String title) {
this.title = title;
}
}
import java.util.Comparator;
/**
* 新闻排序类:按照点击量降序、发布时间降序、标题升序
* 实现Comparator接口,与实体类分离
*/
public class NewsSort implements Comparator<NewsItem2>{
@Override
public int compare(NewsItem2 o1, NewsItem2 o2) {
int result = o1.getHits() - o2.getHits();
if(result==0){
result = o1.getPubDate().compareTo(o2.getPubDate());
if(result==0){
result = o1.getTitle().compareTo(o2.getTitle());
if(result!=0){
return -result;
}
}
}
return result;
}
}
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
/**
* 测试新闻排序
*/
public class NewsSortTest {
//容器+Comparator接口,比较器
public static <T> void listSort(List<T> list,Comparator<T> com){
Object[] arr = list.toArray();
arrSort(arr,com);
for(int i=0;i<arr.length;i++){
list.set(i, (T) arr[i]);
}
}
//数组排序,Comparator接口,比较器
public static <T> void arrSort(Object[] arr,Comparator<T> com){
int len = arr.length;
boolean sort = true;
for(int j=0;j<len-1;j++){
sort = true;
for(int i=0;i<len-1-j;i++){
Object temp;
if(com.compare((T)arr[i], (T)arr[i+1])<0){
temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
sort = false;
}
}
if(sort){
break;
}
}
}
public static void main(String[] args){
List<NewsItem2> list = new ArrayList<NewsItem2>();
list.add(new NewsItem2(5000,new Date(),"这是一个自定义类比较大小测试"));
list.add(new NewsItem2(1000,new Date(System.currentTimeMillis()-1000*60*60),"测试测试"));
list.add(new NewsItem2(5000,new Date(),"我是自定义类"));
list.add(new NewsItem2(1000,new Date(),"这是一个自定义类比较大小测试"));
list.add(new NewsItem2(100,new Date(),"这是一个自定义类比较大小测试"));
listSort(list,new NewsSort());
NewsItem2 item = new NewsItem2();
DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
for(int i=0;i<list.size();i++){
item = list.get(i);
System.out.println("标题:"+item.getTitle() +"\t"+"点击量:"+item.getHits()+"\t"+"发布时间:"+format.format(item.getPubDate()));
}
}
}
3、排序容器类:TreeSet和TreeMap是可以排序的容器
(1)总结
TreeSet:数据元素可以排序且不可重复,要求元素可以排序,否则需要给元素提供业务排序类
添加数据时排序,数据更改不会改变原来的顺序;
不要修改数据,否则可能重复
TreeMap:要求键可以排序,或者给键提供业务排序类;
其他与TreeSet同理
(2)TreeSet排序
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
/**
* 1、给NewsItem对象排序,NewsItem已经实现Comparable接口可以排序,所以可以直接用TreeSet进行排序
* 2、给NewsItem2对象排序,NewsItem2不可以排序,所以需要业务排序类进行排序,这里使用匿名内部类实现Comparator接口
*
*/
public class TreeSetTest1 {
public static void test1(){
NewsItem item1 = new NewsItem(500,new Date(),"这是一个TreeSet排序测试");
NewsItem item2 = new NewsItem(3000,new Date(),"这是一个TreeSet排序测试");
NewsItem item3 = new NewsItem(20,new Date(),"这是一个TreeSet排序测试");
Set<NewsItem> set = new TreeSet<NewsItem>();
set.add(item1);
set.add(item2);
set.add(item3);
for(Iterator iter = set.iterator();iter.hasNext();){
//对点击量做升序排序了
System.out.println(((NewsItem)iter.next()).getHits());
}
}
public static void test2(){
NewsItem2 item1 = new NewsItem2(500,new Date(),"这是一个TreeSet排序测试");
NewsItem2 item2 = new NewsItem2(3000,new Date(),"这是一个TreeSet排序测试");
NewsItem2 item3 = new NewsItem2(20,new Date(),"这是一个TreeSet排序测试");
Set<NewsItem2> set = new TreeSet<NewsItem2>(new Comparator<NewsItem2>(){
@Override
public int compare(NewsItem2 o1, NewsItem2 o2) {
int result = o1.getHits() - o2.getHits();
if(result==0){
result = o1.getPubDate().compareTo(o2.getPubDate());
if(result==0){
result = o1.getTitle().compareTo(o2.getTitle());
if(result!=0){
return -result;
}
}
}
return result;
}
});
set.add(item1);
set.add(item2);
set.add(item3);
for(Iterator iter = set.iterator();iter.hasNext();){
//对点击量做升序排序了
System.out.println(((NewsItem2)iter.next()).getHits());
}
}
public static void main(String[] args) {
test1();
test2();
}
}
(3)TreeMap排序
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
/**
* 1、给NewsItem对象排序,NewsItem已经实现Comparable接口可以排序,所以可以直接用TreeSet进行排序
* 2、给NewsItem2对象排序,NewsItem2不可以排序,所以需要业务排序类进行排序,这里使用匿名内部类实现Comparator接口
*/
public class TreeMapTest {
public static void test1(){
NewsItem item1 = new NewsItem(500,new Date(),"这是一个TreeSet排序测试");
NewsItem item2 = new NewsItem(3000,new Date(),"这是一个TreeSet排序测试");
NewsItem item3 = new NewsItem(20,new Date(),"这是一个TreeSet排序测试");
Map<NewsItem,String> map = new TreeMap<NewsItem,String>();
map.put(item1, "Test");
map.put(item2, "Test");
map.put(item3, "Test");
Set<NewsItem> set = map.keySet();
for(Iterator iter = set.iterator();iter.hasNext();){
//对点击量做升序排序了
System.out.println(((NewsItem)iter.next()).getHits());
}
}
public static void test2(){
NewsItem2 item1 = new NewsItem2(500,new Date(),"这是一个TreeSet排序测试");
NewsItem2 item2 = new NewsItem2(3000,new Date(),"这是一个TreeSet排序测试");
NewsItem2 item3 = new NewsItem2(20,new Date(),"这是一个TreeSet排序测试");
Map<NewsItem2,String> map = new TreeMap<NewsItem2,String>(new Comparator<NewsItem2>(){
@Override
public int compare(NewsItem2 o1, NewsItem2 o2) {
int result = o1.getHits() - o2.getHits();
if(result==0){
result = o1.getPubDate().compareTo(o2.getPubDate());
if(result==0){
result = o1.getTitle().compareTo(o2.getTitle());
if(result!=0){
return -result;
}
}
}
return result;
}
});
map.put(item1, "Test");
map.put(item2, "Test");
map.put(item3, "Test");
Set<NewsItem2> set = map.keySet();
for(Iterator iter = set.iterator();iter.hasNext();){
//对点击量做升序排序了
System.out.println(((NewsItem2)iter.next()).getHits());
}
}
public static void main(String[] args) {
test1();
test2();
}
}
4、工具类java.util.Collections
sort(List list):升序
sort(List list,Comparator c):自定义排序
reverse(List list):反转
shuffle(list):洗牌,打乱顺序
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* Collections类的方法测试
*1、 sort(List list):升序
* sort(List list,Comparator c):自定义排序
*2、reverse(List list):反转
*3、shuffle(list):洗牌,打乱顺序
*/
public class CollectionsTest {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(5);
list.add(7);
list.add(3);
list.add(8);
list.add(0);
System.out.println("原始顺序:"+list.toString());
/**
* 反转
*/
Collections.reverse(list);
System.out.println("反转顺序:"+list.toString());
/**
* 排序:升序和降序
*/
//升序排序
Collections.sort(list); //升序
System.out.println("升序排序"+list.toString());
//匿名内部类降序排序
Collections.sort(list, new Comparator<Integer>(){
@Override
public int compare(Integer o1, Integer o2) {
if(o1 > o2){
return -1;
}else if(o1 == o2){
return 0;
}else{
return 1;
}
}
});
System.out.println("降序排序"+list.toString());
/**
* 洗牌,打乱顺序
*/
//洗牌
List<Integer> cards = new ArrayList<Integer>();
for(int i=0;i<54;i++){
cards.add(i);
}
Collections.shuffle(cards);
//发牌
List<Integer> p1 = new ArrayList<Integer>();
List<Integer> p2 = new ArrayList<Integer>();
List<Integer> p3 = new ArrayList<Integer>();
for(int i=0;i<54;i+=3){
p1.add(cards.get(i));
p2.add(cards.get(i+1));
p3.add(cards.get(i+2));
}
System.out.println("P1:"+p1.toString());
System.out.println("P2:"+p2.toString());
System.out.println("P2:"+p3.toString());
}
}