该用户从未签到
|
根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还要好呢?使用现有的类的另一个好处是代码易于阅读和维护,这篇文章主要讲的是如何使用现有的类库对数组和各种Collection容器进行排序,(文章中的一 部分例子来自《Java Developers Almanac 1.4》)- b* ~) [5 f X5 o
( O& l7 @: S/ X
首先要知道两个类:java.util.Arrays和java.util.Collections(注意和Collection的区 别)Collection是集合框架的顶层接口,而Collections是包含了许多静态方法。我们使用Arrays对数组进行排序,使用 Collections对结合框架容器进行排序,如ArraysList,LinkedList等。
; Q) k E+ u9 H/ J3 C3 l/ _
$ O: \$ A7 ?, E0 ?. v例子中都要加上import java.util.*和其他外壳代码,如类和静态main方法,我会在第一个例子里写出全部代码,接下来会无一例外的省略。- N+ O0 S5 j" N: j' ]- j0 F$ F
6 {3 _" i" d$ T& h5 M+ W7 _对数组进行排序% w* V2 t! b2 c1 b: v8 t5 x. L
# L- _9 `. L- M; F比如有一个整型数组:' |; K& v( k( Y4 v8 J* W
1 P) ^ v. h' o5 f* d# u1 r
int[] intArray = new int[] {4, 1, 3, -23};
" q6 W ?2 q& a8 H8 ?我们如何进行排序呢?你这个时候是否在想快速排序的算法?看看下面的实现方法:' i0 G: Q p) w) ^2 D3 G4 T5 @
& @6 F2 g: \5 Q% ]+ gimport java.util.*; 6 ?9 o9 M& [1 q$ }& @4 @% M
public class Sort{ . D0 m0 { D8 G: k5 |5 M2 N1 d
public static void main(String[] args){ . }$ i0 f7 j6 u B" q. Q
int[] intArray = new int[] {4, 1, 3, -23}; 4 X, H8 T8 t" f
Arrays.sort(intArray); # A" U' x# T9 ~. ~; K9 f& L5 d5 j- r
}
: D, b& }$ W0 @' e}
6 e$ K9 ]! @; y: L) L7 @# B这样我们就用Arrays的静态方法sort()对intArray进行了升序排序,现在数组已经变成了{-23,1,3,4}.; t; r H. u+ I% @" k
8 O2 U( _) V# V. R1 y
如果是字符数组:6 I1 L' M3 Y# |# m8 K1 ^
& v+ p/ E( b% O4 f3 G) o
String[] strArray = new String[] {"z", "a", "C"};
. f( R) ]6 M( {1 i# E5 S) k我们用:
' o/ M! L. J" D: x' P, N$ s
; K5 l7 m! u/ ^Arrays.sort(strArray); ' n9 F$ ?/ P! y# B2 o
进行排序后的结果是{C,a,z},sort()会根据元素的自然顺序进行升序排序。如果希望对大小写不敏感的话可以这样写:- R: Z i( n$ R/ z
! A/ O5 D: |& U7 y7 OArrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);
; J2 c- l Y8 I; x+ ~当然我们也可以指定数组的某一段进行排序比如我们要对数组下表0-2的部分(假设数组长度大于3)进行排序,其他部分保持不变,我们可以使用:
5 J" z: t; ?8 c2 A: X9 }, ]) h1 B4 \ H: G
Arrays.sort(strArray,0,2);
& Z0 W0 Z0 t; Y @9 y" _这样,我们只对前三个元素进行了排序,而不会影响到后面的部分。
% z1 Z3 ~) L0 h7 f) m2 {' B9 _) z& o2 {9 H7 S
当然有人会想,我怎样进行降序排序?在众多的sort方法中有一个2 F* j. a# X6 f" m; s* H
- e4 p! E; e+ ]# f
sort(T[] a, Comparator<? super T> c) ) B7 u4 b+ f% L* }" Q7 h5 u; ?
我们使用Comparator获取一个反序的比较器即可,Comparator会在稍后讲解,以前面的intArray[]为例:
6 i+ p/ D% N0 E% \. h: x6 H+ [# R% N! ~ G+ T$ x9 z1 o: ]' U. X
Arrays.sort(intArray,Comparator.reverseOrder()); 4 J: o7 M8 Y1 \# X, k3 R* \
这样,我们得到的结果就是{4,3,1,-23}。如果不想修改原有代码我们也可以使用:7 D- w: y7 }% g: f# `0 G; X
# ~& N6 n* m) A% PCollections.reverse(Arrays.asList(intArray));
3 m; s k5 I. a/ N得到该数组的反序。结果同样为4,3,1,-23}。2 e8 u/ ^( g" i, r H8 E( E
8 ^/ i( m" J, ]% F7 B, e0 j9 B现在的情况变了,我们的数组里不再是基本数据类型(primtive type)或者String类型的数组,而是对象数组。这个数组的自然顺序是未知的,因此我们需要为该类实现Comparable接口,比如我们有一个Name类:
& E1 }0 c# s6 n; T$ I
7 b1 [1 |8 p* f( a1 Wclass Name implements Comparable<Name>{
8 e, R& g' _, W* A" n public String firstName,lastName;
: x' \: {) A7 }6 s- Y public Name(String firstName,String lastName){ % A3 b2 l* g c2 r9 e4 y& A# l
this.firstName=firstName; 5 `1 a/ G! L/ H6 h) {; H
this.lastName=lastName;
9 W) a6 i+ f& M! c8 \, u } ! V2 _. y" ?# R" K1 i/ ~! {) e
public int compareTo(Name o) { //实现接口 - r4 S- H+ I' i8 U0 G
int lastCmp=lastName.compareTo(o.lastName);
6 ]2 k& {' P' E9 w1 \0 P4 P ` return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName));
* R) E. n" U5 \% C/ y, q2 x; J } , C7 @2 Q: x& X# ?! m K# s
public String toString(){ //便于输出测试 - H; d' f% K) s M
return firstName+" "+lastName; 8 ]: E2 s+ g6 i1 V f, b
}
. F7 [/ {' {1 d' v} & W6 w: N- }1 _. n2 L
这样,当我们对这个对象数组进行排序时,就会先比较lastName,然后比较firstName 然后得出两个对象的先后顺序,就像compareTo(Name o)里实现的那样。不妨用程序试一试:
9 b) H8 w6 K( ]* R* n* A% s' |' F# M- o! p( m( l
import java.util.*;
4 ^) J8 u0 G$ I5 n7 u" F: Z public class NameSort { % q9 Z1 U0 C! D/ Q! Q
public static void main(String[] args) {
; F" _3 a4 R. J. M. h5 ^ Name nameArray[] = {
& c. r; V+ P7 t5 W: [ new Name("John", "Lennon"), ( \, ]7 ?9 ^+ j) E9 a
new Name("Karl", "Marx"), 6 f) O, G: W- s% R; r; p
new Name("Groucho", "Marx"),
6 ?, M+ K) b6 g9 p new Name("Oscar", "Grouch")
% [0 M( f# c* V5 d. E6 M }; |
|