该用户从未签到
|
根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还要好呢?使用现有的类的另一个好处是代码易于阅读和维护,这篇文章主要讲的是如何使用现有的类库对数组和各种Collection容器进行排序,(文章中的一 部分例子来自《Java Developers Almanac 1.4》)
) i0 @% p! ^) B T
* k! N$ S+ M! [! X首先要知道两个类:java.util.Arrays和java.util.Collections(注意和Collection的区 别)Collection是集合框架的顶层接口,而Collections是包含了许多静态方法。我们使用Arrays对数组进行排序,使用 Collections对结合框架容器进行排序,如ArraysList,LinkedList等。3 ^* i. K' a& t" o* q/ e9 d
9 F* a/ n: A5 {! ? G$ g }
例子中都要加上import java.util.*和其他外壳代码,如类和静态main方法,我会在第一个例子里写出全部代码,接下来会无一例外的省略。* F5 N3 m6 w: x8 [8 ^5 ?
+ @* u/ h8 d* [- p2 [1 F: s
对数组进行排序$ D) N0 \( G5 e- S" K$ X; d+ ^
1 E# W& M0 L9 I/ n' R
比如有一个整型数组:
/ T1 S- h8 m# B8 [1 ^# }7 Z! {/ Q% j& H( q) W8 Z( B1 K
int[] intArray = new int[] {4, 1, 3, -23}; 1 F6 N" s( x; U3 p( M# E. c9 l
我们如何进行排序呢?你这个时候是否在想快速排序的算法?看看下面的实现方法:
/ C! b. E- N+ S) l, `2 F; `1 T- o) b% m9 d5 r- z8 W1 y$ c
import java.util.*;
W8 \' |, A- Q* @8 Kpublic class Sort{ & _& O' }* z% T0 e4 s" Z
public static void main(String[] args){
7 h# ?7 J' z+ M0 J7 J& \( D int[] intArray = new int[] {4, 1, 3, -23};
a a! T4 U/ r) K& ` Arrays.sort(intArray);
& `) U- h' [, ?; w, M }
! I3 q( q, j# u1 |. w" \+ B8 ?}
. d+ J2 P v. [+ [2 \# O这样我们就用Arrays的静态方法sort()对intArray进行了升序排序,现在数组已经变成了{-23,1,3,4}.
. _2 g+ ` s1 }! |2 {
" |+ w- q* ^& t! v# w如果是字符数组:
9 s r. [. J- Q2 s
) ~+ K( Y+ q2 _1 j8 h3 EString[] strArray = new String[] {"z", "a", "C"}; $ j9 o" `$ n6 Z) P
我们用:& H1 z9 s/ d; ^% r! O
9 H. _3 @- D* Z- _# cArrays.sort(strArray); ! j4 u2 c! m/ ^+ i+ C% I
进行排序后的结果是{C,a,z},sort()会根据元素的自然顺序进行升序排序。如果希望对大小写不敏感的话可以这样写:% E* X, H) A+ b# x
5 }( {0 i3 @* j* d) t/ v `4 ^9 |. q" IArrays.sort(strArray, String.CASE_INSENSITIVE_ORDER); 2 Z/ F3 }6 |. B3 V9 @
当然我们也可以指定数组的某一段进行排序比如我们要对数组下表0-2的部分(假设数组长度大于3)进行排序,其他部分保持不变,我们可以使用:
0 C9 P, ^8 J U( l# d; e% j. {7 o, z- _6 ?
Arrays.sort(strArray,0,2);
: n; b* w+ U' Z) U% j$ l0 e这样,我们只对前三个元素进行了排序,而不会影响到后面的部分。
7 F5 x) ?! N* N4 p% X; Q* N
- |3 ^$ D. X% r当然有人会想,我怎样进行降序排序?在众多的sort方法中有一个/ q3 H3 b: p4 w0 p
8 H5 o: d6 Y6 T0 F! ~; ~
sort(T[] a, Comparator<? super T> c)
: h7 J P- v, a2 a/ P1 U我们使用Comparator获取一个反序的比较器即可,Comparator会在稍后讲解,以前面的intArray[]为例:
! [" ~$ g8 ?, t# u+ N
+ h% x7 `% h: [: kArrays.sort(intArray,Comparator.reverseOrder());
@7 f& w# P1 F9 k! Q这样,我们得到的结果就是{4,3,1,-23}。如果不想修改原有代码我们也可以使用:
. }9 S/ a* `) R0 N3 C4 z' X' u# q3 _: R. s
Collections.reverse(Arrays.asList(intArray)); 6 a' b% A" s+ b5 c; l" l# p0 V
得到该数组的反序。结果同样为4,3,1,-23}。/ \+ p# z3 s$ N& q: V% H+ z! u5 L
! }# O) c: x6 Y2 M/ U2 I& F q
现在的情况变了,我们的数组里不再是基本数据类型(primtive type)或者String类型的数组,而是对象数组。这个数组的自然顺序是未知的,因此我们需要为该类实现Comparable接口,比如我们有一个Name类:3 H( w! c. m% C* g
# o2 v& Y1 x, n' U ?8 Z; f
class Name implements Comparable<Name>{
' x! g! V; ^2 r- W# P; G8 J" Y public String firstName,lastName;
' o' R% z" w9 ~6 u. g. v: M public Name(String firstName,String lastName){
1 o6 K" n, J3 E) R( d( A this.firstName=firstName;
5 x% a6 j8 m6 M7 Z) v0 d this.lastName=lastName;
[5 S+ r f9 v$ L8 b7 b- b5 q1 Q }
3 h8 `: ~4 y# }7 A; r public int compareTo(Name o) { //实现接口 / l; y8 @0 F* p2 E* A2 w: [+ m: D
int lastCmp=lastName.compareTo(o.lastName);
3 S1 M$ v8 c2 G6 X% h return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName)); - c6 L$ }. l o1 Z9 T6 K3 X
}
8 v& \, K, j# O) r' v8 I public String toString(){ //便于输出测试 5 R: O% y3 r1 ~0 x
return firstName+" "+lastName; 3 ~/ y) Q- v( M: ]# \
}
3 n1 H) I: O3 X} ! ?; L& y# U1 s; D( f W
这样,当我们对这个对象数组进行排序时,就会先比较lastName,然后比较firstName 然后得出两个对象的先后顺序,就像compareTo(Name o)里实现的那样。不妨用程序试一试:
$ _% l, c$ |4 c7 Z9 |7 l; `) u8 f$ p+ n
import java.util.*; " w. e L& P$ @2 K) v8 H
public class NameSort {
) [& U, U- {1 ]8 d public static void main(String[] args) { $ H( q1 |' o4 a0 @
Name nameArray[] = {
( \8 g+ @) r. V2 s new Name("John", "Lennon"),
7 F/ N+ r$ Z0 ^: Z- a. c new Name("Karl", "Marx"), : J8 _+ P4 G3 J9 ]$ S
new Name("Groucho", "Marx"), 6 B7 s. V7 V) \' w4 P4 R; H
new Name("Oscar", "Grouch")
+ K F$ t& p5 N, Z7 x1 ^ }; |
|