该用户从未签到
|
根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还要好呢?使用现有的类的另一个好处是代码易于阅读和维护,这篇文章主要讲的是如何使用现有的类库对数组和各种Collection容器进行排序,(文章中的一 部分例子来自《Java Developers Almanac 1.4》)
1 s. K- g$ S/ f1 R+ m7 K' I# U( M! W
首先要知道两个类:java.util.Arrays和java.util.Collections(注意和Collection的区 别)Collection是集合框架的顶层接口,而Collections是包含了许多静态方法。我们使用Arrays对数组进行排序,使用 Collections对结合框架容器进行排序,如ArraysList,LinkedList等。7 b9 \$ F- d) [* S3 S
% K) G m$ O8 U& j' e* @7 [
例子中都要加上import java.util.*和其他外壳代码,如类和静态main方法,我会在第一个例子里写出全部代码,接下来会无一例外的省略。
+ W: `5 n" R! ~& n1 x
+ L* g2 d S% U2 ]* T7 P, S对数组进行排序) A; g" F% H O* @# V0 ?
: g9 C& Q& g4 k ?比如有一个整型数组:
* v" G: ^% Y2 ]5 ~# L* F ~& G' @# x% A9 t
int[] intArray = new int[] {4, 1, 3, -23};
/ I" X. o r% I! X6 w( x$ f7 t$ |我们如何进行排序呢?你这个时候是否在想快速排序的算法?看看下面的实现方法:
$ u7 E$ h# s. d; Y# T- I: j3 V6 K% s- o# i* j' B) w; O% i
import java.util.*; ! g7 C" J' H8 d5 q+ X$ B" j+ {' ]
public class Sort{
5 y5 }/ A$ ]. S7 m% I/ q7 s, l public static void main(String[] args){
# z6 S: h* h( ~+ i& a int[] intArray = new int[] {4, 1, 3, -23};
; c3 P2 D! {- ]9 b; o Arrays.sort(intArray); / _# c( @5 F" I: G: f4 L
} 6 p' y9 j" e8 h2 x7 J1 `! J6 E# j
}
% o' \3 i2 ]0 c' f- E* ~+ h这样我们就用Arrays的静态方法sort()对intArray进行了升序排序,现在数组已经变成了{-23,1,3,4}. B, N7 ]8 L/ K1 K& N
7 B4 z- y1 S: J$ _! I* y; }' n' G' x% E如果是字符数组:4 s3 C' V/ ?( [9 N5 } {
f k) A) C. T2 i
String[] strArray = new String[] {"z", "a", "C"};
1 w/ G, N O' o* B8 V# ^$ Y我们用:
! o' c& t8 e- y+ B1 Y b/ X' ?
- }* Y2 i1 U( T: E) YArrays.sort(strArray); 6 _( P& {. C( ?- A/ ?$ m
进行排序后的结果是{C,a,z},sort()会根据元素的自然顺序进行升序排序。如果希望对大小写不敏感的话可以这样写: x) O7 b) O( Q) C( Z; S
+ N- [ d2 t0 ^2 C$ J
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER); 2 p& s% Z# g( d( p
当然我们也可以指定数组的某一段进行排序比如我们要对数组下表0-2的部分(假设数组长度大于3)进行排序,其他部分保持不变,我们可以使用:
x8 k) `. V1 q" D
E3 N4 I; u* [2 ~Arrays.sort(strArray,0,2); / c2 H6 g5 ^ n# g
这样,我们只对前三个元素进行了排序,而不会影响到后面的部分。/ O: y+ {2 m9 l' Z% y# Y
" {" [( J+ ] c# u4 i当然有人会想,我怎样进行降序排序?在众多的sort方法中有一个
( [0 K3 \0 I X2 _- T0 a
& `( W+ p) g @% s& S. o) ^sort(T[] a, Comparator<? super T> c) & e7 f# n) |& |, F
我们使用Comparator获取一个反序的比较器即可,Comparator会在稍后讲解,以前面的intArray[]为例:' v5 [* L1 H/ N# @
7 `+ V$ O8 B; Y8 p
Arrays.sort(intArray,Comparator.reverseOrder()); 9 K" v- [5 r3 b( g
这样,我们得到的结果就是{4,3,1,-23}。如果不想修改原有代码我们也可以使用:+ h+ F& f4 Z4 G' J
7 `* r7 y' s$ C0 D ?0 G: B7 `) t( j
Collections.reverse(Arrays.asList(intArray));
5 j5 }1 i4 w8 v! V- L3 ]( Z" p得到该数组的反序。结果同样为4,3,1,-23}。# w5 z; C, \" w0 I6 A A! F
; O5 w7 O3 @/ L& Z2 S现在的情况变了,我们的数组里不再是基本数据类型(primtive type)或者String类型的数组,而是对象数组。这个数组的自然顺序是未知的,因此我们需要为该类实现Comparable接口,比如我们有一个Name类:
. b. f4 O/ X5 J7 c* R( t y
) r6 d& w5 W3 r" g/ ]/ G$ ^9 oclass Name implements Comparable<Name>{ & N: d7 s' d: h
public String firstName,lastName; ; M" P2 r+ L* Y# \ F2 X8 _6 E
public Name(String firstName,String lastName){
4 l* U) ^ Z& j# X this.firstName=firstName;
4 b& j' \3 b1 M# F8 N6 L this.lastName=lastName; 1 n8 W$ W, i3 w* T' F: h
}
+ ]+ r: N# A9 O+ \ public int compareTo(Name o) { //实现接口 : x) u1 a2 v m4 Z& D/ t! n
int lastCmp=lastName.compareTo(o.lastName);
1 C' y6 N$ j. y return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName));
1 D/ b& M# |2 y: B/ v p% x } 2 P, ?9 ^; M, s( |
public String toString(){ //便于输出测试 0 S5 m$ g5 o4 S& p) c7 e+ v. K
return firstName+" "+lastName; ) M; l7 e3 _/ X: r
} 7 M8 H' s6 F5 P5 D/ W
} 7 f" w3 n d& V8 Y1 | o' w
这样,当我们对这个对象数组进行排序时,就会先比较lastName,然后比较firstName 然后得出两个对象的先后顺序,就像compareTo(Name o)里实现的那样。不妨用程序试一试:: F3 p: W! H7 ^# M4 p3 q
8 E5 |+ W" o5 k( w( R; J# S: w% f import java.util.*; 8 M% B6 l; H* l6 M1 y' w1 U
public class NameSort { : |! c( N- X( u" D8 E
public static void main(String[] args) {
. I4 R3 S) I' H7 J# a1 p Name nameArray[] = { * {3 D+ R; i% ~1 t( m
new Name("John", "Lennon"), & a1 ^. Y* ]$ e, c- a' u
new Name("Karl", "Marx"),
8 D+ T! s- P% y new Name("Groucho", "Marx"), 5 ]; W' ~$ |! L; H
new Name("Oscar", "Grouch")
% w& l1 Y! b8 }" S9 C+ p4 a }; |
|