TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还要好呢?使用现有的类的另一个好处是代码易于阅读和维护,这篇文章主要讲的是如何使用现有的类库对数组和各种Collection容器进行排序,(文章中的一 部分例子来自《Java Developers Almanac 1.4》)" B; S% j5 j' G
( @7 w8 Y( C0 o* X首先要知道两个类:java.util.Arrays和java.util.Collections(注意和Collection的区 别)Collection是集合框架的顶层接口,而Collections是包含了许多静态方法。我们使用Arrays对数组进行排序,使用 Collections对结合框架容器进行排序,如ArraysList,LinkedList等。* z- a! `. U% [# |
% |+ f2 [5 h2 u4 X, ~例子中都要加上import java.util.*和其他外壳代码,如类和静态main方法,我会在第一个例子里写出全部代码,接下来会无一例外的省略。
8 l) v* j5 d3 }& e5 V7 X h
% Y( k8 A; r6 ~$ Z' q+ Q1 g8 [对数组进行排序
- T4 M: o* t2 x1 ^ y- F* O! b
! P0 W. d: O" ^& b" I( e比如有一个整型数组:
4 \8 p9 Z5 A1 U4 k Q) X* q# e
+ t6 H, R4 T, L6 x: F9 Kint[] intArray = new int[] {4, 1, 3, -23};
; V$ |# h5 F4 _. e5 j我们如何进行排序呢?你这个时候是否在想快速排序的算法?看看下面的实现方法:' A; |& L& s2 _: T# _ _
& Z* v8 d5 w$ W. rimport java.util.*; ' `. n7 ~- o4 W+ h& D# ~& C
public class Sort{
5 r1 M" i8 @. O$ \6 o7 w& X( o# i public static void main(String[] args){ , B/ J9 ]* \6 s; o
int[] intArray = new int[] {4, 1, 3, -23};
" J2 R1 N( i* V: X Arrays.sort(intArray); Y2 X! A+ C* `! I/ K9 b( D3 C8 Y
} $ U" d' Q" T- U* ]
} + {# M- P/ w C6 a3 M% u7 c
这样我们就用Arrays的静态方法sort()对intArray进行了升序排序,现在数组已经变成了{-23,1,3,4}.
7 ~/ B) ~2 V. z1 o* M; x; B I7 r# w& Z" S/ i7 U
如果是字符数组:3 H* m- ~- W9 e R7 }
4 X. c2 a7 E9 W% tString[] strArray = new String[] {"z", "a", "C"}; 5 s/ p& l( n7 T. Y
我们用:
% }9 S+ v" S! ~2 A8 P3 X8 F3 \' o4 t' E
Arrays.sort(strArray); , ?' a$ A2 y5 \8 h l
进行排序后的结果是{C,a,z},sort()会根据元素的自然顺序进行升序排序。如果希望对大小写不敏感的话可以这样写:
0 ~8 }5 c3 I: F, }
! [; f4 E. b- T. K7 s ?- U; {Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER); ! [2 D% x" {1 \' w4 j& a) E( E8 J
当然我们也可以指定数组的某一段进行排序比如我们要对数组下表0-2的部分(假设数组长度大于3)进行排序,其他部分保持不变,我们可以使用:3 u0 s! V Z1 H& P+ T* E
/ R- v, U! a- j D" s1 Z
Arrays.sort(strArray,0,2); \- R4 ?/ O+ B ~5 }' G* {% y
这样,我们只对前三个元素进行了排序,而不会影响到后面的部分。
! z0 a: t3 J8 M% M: v g% k: p2 `8 \5 w; f) L2 d$ X: H
当然有人会想,我怎样进行降序排序?在众多的sort方法中有一个
1 U8 `' ^8 ~) i& @# k. K- E& M/ P4 K4 q
sort(T[] a, Comparator<? super T> c)
# h' F; T2 K L. R h( K我们使用Comparator获取一个反序的比较器即可,Comparator会在稍后讲解,以前面的intArray[]为例:
1 Z: U( E& u* M0 U; a6 h% M; b7 K, q: J6 r7 Z5 m- j: e
Arrays.sort(intArray,Comparator.reverseOrder()); " [ k% C4 b8 |7 r2 L1 ~7 i* K
这样,我们得到的结果就是{4,3,1,-23}。如果不想修改原有代码我们也可以使用:& ~1 `* h _6 C' u
5 F: b: ^ u, r/ S7 A nCollections.reverse(Arrays.asList(intArray)); 6 l& S* N0 G/ U. h4 V
得到该数组的反序。结果同样为4,3,1,-23}。
l# I/ @% P* S$ h" g* ~* z1 U7 g7 K3 ^0 F
现在的情况变了,我们的数组里不再是基本数据类型(primtive type)或者String类型的数组,而是对象数组。这个数组的自然顺序是未知的,因此我们需要为该类实现Comparable接口,比如我们有一个Name类:6 O9 P* q& I+ V4 x
/ ~) p% z1 ` O' \0 P, N
class Name implements Comparable<Name>{ 1 S. {4 f4 I3 N( n( a) `
public String firstName,lastName; / l( g' n$ e( _( e$ Y3 U
public Name(String firstName,String lastName){ ) ?5 _7 ]% r8 C( e( I
this.firstName=firstName;
4 J5 v1 U8 \3 V0 ^ @ this.lastName=lastName; 1 K: U- f H1 }: G, d" }
} / r6 o0 r( y: X* X) n' J
public int compareTo(Name o) { //实现接口 ; p V6 }/ u; }% v0 u7 Y4 v
int lastCmp=lastName.compareTo(o.lastName);
/ y/ D& E s2 m/ K: o8 H/ f return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName)); & ?/ Y% S3 t5 w3 r) Z0 f! N3 N
}
; M2 G; [' r# q6 y8 [" z public String toString(){ //便于输出测试 ; c! x! J( @- f& d/ i
return firstName+" "+lastName; 2 Z: _6 M' E! J$ g: j2 S
} ; P( S2 f$ L$ I
}
. y j1 C9 X6 G这样,当我们对这个对象数组进行排序时,就会先比较lastName,然后比较firstName 然后得出两个对象的先后顺序,就像compareTo(Name o)里实现的那样。不妨用程序试一试:) T2 ^4 Q% a% _
4 ?' l3 [ j$ _8 _7 j# x
import java.util.*;
/ y" p( _7 o7 ]: n, \, P% s' y public class NameSort { 3 @' b2 ^- J" A
public static void main(String[] args) { " s& D# {2 ]+ |$ u$ r% E% k
Name nameArray[] = { , o2 V) |( ^# q/ z4 q
new Name("John", "Lennon"),
' H# c1 h3 w" \4 K' z) }. j# K new Name("Karl", "Marx"),
# S. ]# Q3 D. J, z new Name("Groucho", "Marx"),
4 t* g! M# A$ S new Name("Oscar", "Grouch")
2 e" Y F+ n0 t A K }; |
|