JAVA数组排序&list排序&map排序&中文排序

时间:2023-01-23 08:00:13

 1.数组排序及list排序       

 

        在JAVA中对数组排序或list元素排序,JAVA提供了Arrays.sort()及Collections.sort(),使用者只要正确调用即可,不需要使用者自己写排序算法的实现。当然如果数据量大,并且要求效率高的话,还是需要自己选择适当排序算法的自己写代码实现。

 

         打开Collections.sort()源码,发现sort()重载了2次。

public static <T extends Comparable<? super T>> void sort(List<T> list) {
Object[] a = list.toArray();
Arrays.sort(a);
ListIterator<T> i = list.listIterator();
for (int j=0; j<a.length; j++) {
i.next();
i.set((T)a[j]);
}
}


public static <T> void sort(List<T> list, Comparator<? super T> c) {
Object[] a = list.toArray();
Arrays.sort(a, (Comparator)c);
ListIterator i = list.listIterator();
for (int j=0; j<a.length; j++) {
i.next();
i.set(a[j]);
}
}

       看源码知道Collections.sort()只对list类型进行排序,将list转换为数组,然后再用Arrays.sort()进行真正的排序。下面重点认识Arrays.sort()即可。

       看看Arrays.sort()进行了什么样的重载。

JAVA数组排序&list排序&map排序&中文排序

 

         Arrays.sort()支持所有基本数据类型的排序(byte,char,short,int,float,double,long)、Object对象排序及自定义的对象排序(需要实现Comparable接口或传入一个Comparator比较器,下面将会讲解)。

       对于元素类型是基本数据类型的数组,排序很简单,只需将数组传给Arrays.sort()即可。

package sort;

import java.util.Arrays;

public class JavaSort {
public static void main(String[] args) {
int[] x={5,2,10,45,6,4,69};
System.out.println("排序前......");
System.out.println(Arrays.toString(x));
Arrays.sort(x);//排序,默认是从小到大
System.out.println("排序后......");
System.out.println(Arrays.toString(x));
}
}

运行结果
排序前......
[5, 2, 10, 45, 6, 4, 69]
排序后......
[2, 4, 5, 6, 10, 45, 69]

 

     对象排序,则必须告诉JVM排序规则。

    

     如果你留意过Integer,Double,Long,String等这些类,会发现他们都实现了Comparable接口,Comparable接口定义如下

public interface Comparable<T> {
public int compareTo(T o);
}

     

     Integer类中的compareTo()方法

public int compareTo(Integer anotherInteger) {
int thisVal = this.value;
int anotherVal = anotherInteger.value;
return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
}


    两对象比较,前者<后者,返回-1;前者>后者,返回1;前者=后者,返回0.

   

     下面写个小例子看下,两个user比较,按照age排序,如果age相等就按照姓名(中文)的拼音顺序排序。由于这例子中涉及到中文按拼音顺序排序。所以先看个中文排序例子。

      中文按照拼音顺序排序。

package sort;

import java.text.Collator;
import java.util.Arrays;

public class JavaSort {
public static void main(String[] args) {
Collator cmp=Collator.getInstance(java.util.Locale.CHINA);//获得中文比较器
String[] x={"张三","李四","赵五","孙六"};
System.out.println("排序前......");
System.out.println(Arrays.toString(x));
Arrays.sort(x,cmp);//告诉Arrays.sort要按照cmp这个比较规则进行比较
System.out.println("排序后......");
System.out.println(Arrays.toString(x));

}
}

运行结果


排序前......
[张三, 李四, 赵五, 孙六]
排序后......
[李四, 孙六, 张三, 赵五]

 

      好了,已经知道中文按照拼音顺序排序的方法了,那么下面来看看user按照age排序,如果age相等,就按照name(中文)排序的小例子.

package sort;

import java.text.Collator;
import java.util.Locale;

public class User implements Comparable<User>{

private String name;
private int age;

public User(String name,int age){
this.name=name;
this.age=age;
}

@Override
public int compareTo(User o) {
int c1=this.age<o.getAge()?-1:(this.age==o.getAge()?0:1);//age compare
if(c1!=0) return c1;//如果年龄不相等,则返回比较结果,姓名就不需要比较了
return Collator.getInstance(Locale.CHINA).compare(this.name, o.getName());//返回姓名比较的结果
}

/**
* 为了方便打印user对象,重写toString
*/
public String toString(){
return "{"+this.name+" "+this.age+"}";
}
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

}

package sort;

import java.text.Collator;
import java.util.Arrays;

public class JavaSort {
public static void main(String[] args) {
User[] users={
new User("张三",20),
new User("李四",25),
new User("赵五",18),
new User("孙六",18)
};
System.out.println("排序前......");
System.out.println(Arrays.toString(users));
Arrays.sort(users);
System.out.println("排序后......");
System.out.println(Arrays.toString(users));

}
}


运行结果

 排序前......
[{张三  20}, {李四  25}, {赵五  18}, {孙六  18}]
排序后......
[{孙六  18}, {赵五  18}, {张三  20}, {李四  25}]

 

       上面的user类直接实现了Comparable接口,所以user对象可以进行比较。但是我们开发中,可能会遇到这种情况,比如User类是一个

JavaBean(POJO),初期是没有实现Comparable接口的,现在有需求需要user对象可以进行比较排序,先按照age排序,再按照name排序,不允许对User类进行修改。为了解决这种情况,JAVA提供了Comparator接口,定义如下

public interface Comparator<T> {
int compare(T o1, T o2);
boolean equals(Object obj);
}


        如果你细心,就会发现我上面贴出的Arrays.sort()重载的截图,发现有个sort(T[] a, Comparator<? super T> c);这个方法就是允许你传入一个自己定义的比较器。

package sort;


public class User {

private String name;
private int age;

public User(String name,int age){
this.name=name;
this.age=age;
}


/**
* 为了方便打印user对象,重写toString
*/
public String toString(){
return "{"+this.name+" "+this.age+"}";
}
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

}

package sort;

import java.text.Collator;
import java.util.Comparator;
import java.util.Locale;

public class UserComparator implements Comparator<User>{

@Override
public int compare(User u1, User u2) {
int c1=u1.getAge()<u2.getAge()?-1:(u1.getAge()==u2.getAge()?0:1);//年龄比较
if(c1!=0) return c1;
return Collator.getInstance(Locale.CHINA).compare(u1.getName(), u2.getName());//返回姓名比较的结果
}

}


package sort;

import java.text.Collator;
import java.util.Arrays;

public class JavaSort {
public static void main(String[] args) {
User[] users={
new User("张三",20),
new User("李四",25),
new User("赵五",18),
new User("孙六",18)
};
System.out.println("排序前......");
System.out.println(Arrays.toString(users));
Arrays.sort(users,new UserComparator());//这里的比较器也可以写成匿名类,不需要在写一个UserComparator类了
System.out.println("排序后......");
System.out.println(Arrays.toString(users));

}
}

运行结果
 排序前......
[{张三  20}, {李四  25}, {赵五  18}, {孙六  18}]
排序后......
[{孙六  18}, {赵五  18}, {张三  20}, {李四  25}]

2.Map排序

       Map在实际开发中,会经常被使用到,特别是它的子类HashMap。HashMap是无序存放,就是说遍历得到的结果是随机的,无序的。那能不能对Map进行排序呢?JAVA中提供了TreeMap类,它是有序存放的,按集合中的key排序。先看看TreeMap例子

package sort;

import java.util.Iterator;
import java.util.Map;
import java.util.TreeMap;

public class TreeMapTest {
public static void main(String[] args) {
Map<String,String> map=new TreeMap<String,String>();
map.put("b", "李四");
map.put("c", "赵五");
map.put("a", "张三");
map.put("d", "孙六");
Iterator<String> it=map.keySet().iterator();
while(it.hasNext()){
String key=(String)it.next();
System.out.println(key+" "+map.get(key));
}
}
}

运行结果

a  张三
b  李四
c  赵五
d  孙六


   

 

        TreeMap可以对集合中的key排序,如果key是自己写的一个类呢?那么这时就需要new TreeMap()时,传入构造器。比如

Map<User,String> useMap=new TreeMap<User,String>(new UserComparator());


            TreeMap默认的是按key排序,那能否按value值排序呢?如果对Map的子类有所了解的同学,都知道map中的key-value都是保存在一个Entry类中,那key排序或者value排序,都可以通过Map.Entry<K,V>结合list进行排序。

          

package sort;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

public class TreeMapTest {
public static void main(String[] args) {
Map<String,String> map=new TreeMap<String,String>();
map.put("b", "李四");
map.put("c", "赵五");
map.put("a", "张三");
map.put("d", "孙六");
List<Map.Entry<String,String>> mapList=new ArrayList<Map.Entry<String,String>>(map.entrySet());
Collections.sort(mapList, new Comparator<Map.Entry<String,String>>(){
@Override
public int compare(Entry<String, String> o1,
Entry<String, String> o2) {
Collator cmp=Collator.getInstance(Locale.CHINA);//中文按照拼音排序比较器
return cmp.compare(o1.getValue(), o2.getValue());//如果想按key排序,改成getKey()就OK了
}

});
for(Map.Entry<String, String> m:mapList){
System.out.println(m.getKey()+" "+m.getValue());
}

}
}

运行结果


b  李四
d  孙六
a  张三
c  赵五

    对HashMap,HashTable,LinkedHashMap等Map的子类其实都可以这样处理的。下面把上面程序的TreeMap改成 HashMap,按Key排序。

package sort;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;

public class TreeMapTest {
public static void main(String[] args) {
Map<String,String> map=new HashMap<String,String>();
map.put("b", "李四");
map.put("c", "赵五");
map.put("a", "张三");
map.put("d", "孙六");
List<Map.Entry<String,String>> mapList=new ArrayList<Map.Entry<String,String>>(map.entrySet());
Collections.sort(mapList, new Comparator<Map.Entry<String,String>>(){
@Override
public int compare(Entry<String, String> o1,
Entry<String, String> o2) {
return o1.getKey().compareTo(o2.getKey());//如果想按value排序,改成getValue()就OK了
}

});
for(Map.Entry<String, String> m:mapList){
System.out.println(m.getKey()+" "+m.getValue());
}

}
}

运行结果


a  张三
b  李四
c  赵五
d  孙六