TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还要好呢?使用现有的类的另一个好处是代码易于阅读和维护,这篇文章主要讲的是如何使用现有的类库对数组和各种Collection容器进行排序,(文章中的一 部分例子来自《Java Developers Almanac 1.4》)) c# q: k5 v. f6 E) t
0 o+ k8 G% F8 D+ n0 q: `: |首先要知道两个类:java.util.Arrays和java.util.Collections(注意和Collection的区 别)Collection是集合框架的顶层接口,而Collections是包含了许多静态方法。我们使用Arrays对数组进行排序,使用 Collections对结合框架容器进行排序,如ArraysList,LinkedList等。# U( ]. `/ e) x `8 u% k
! W. C5 R# ?* I5 @8 h4 e例子中都要加上import java.util.*和其他外壳代码,如类和静态main方法,我会在第一个例子里写出全部代码,接下来会无一例外的省略。
( C" U! B4 Z+ j; B6 T
( K) T3 j1 `; l% [, n; ]2 m对数组进行排序. p8 d- p# S+ b" O) C
q; Z1 J; g2 N( V) {9 |9 f0 E比如有一个整型数组:1 q+ n$ B4 g+ V |% S
$ o4 \/ Z: ]# i$ [: E @2 `0 Dint[] intArray = new int[] {4, 1, 3, -23}; + I& P; ], R( S$ Z8 a! m: ~( {
我们如何进行排序呢?你这个时候是否在想快速排序的算法?看看下面的实现方法:
) d5 U- H% p/ l1 J3 B1 L8 `2 H9 Q8 u6 T! c
import java.util.*;
5 P; Q/ N, g6 i0 hpublic class Sort{ - E& Y6 s: c1 g1 V8 x6 M! l
public static void main(String[] args){
0 o5 e1 ]8 i7 w/ ^ int[] intArray = new int[] {4, 1, 3, -23}; * L6 t- K3 b& O: N' {, r
Arrays.sort(intArray); 8 i T8 S/ p" b0 G
} # [; @4 L7 ^0 u; E f
}
( Q% b, \; v% {) U这样我们就用Arrays的静态方法sort()对intArray进行了升序排序,现在数组已经变成了{-23,1,3,4}.$ q$ A" u7 u( p3 G% \! O$ Q5 Q
$ Q6 x$ Y: P" S0 o) D( A7 l6 N
如果是字符数组:
* X; d# q. e5 A6 B7 O4 D* s# U4 \+ M& E" Y
String[] strArray = new String[] {"z", "a", "C"};
( N8 g/ a% @$ g+ ~6 d4 u我们用:
/ S. \6 T* R! s% Y
+ f7 j: V7 m6 w) Y7 p2 R9 NArrays.sort(strArray); 5 B' |$ J3 r2 D4 X& p& H% V: @
进行排序后的结果是{C,a,z},sort()会根据元素的自然顺序进行升序排序。如果希望对大小写不敏感的话可以这样写:2 Z( ?* w/ k7 J# {, l" c4 t, ~# W5 t
6 g* @$ n9 A, z9 ^% {0 [5 @
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER); . k! m7 c2 s N$ \* A8 e
当然我们也可以指定数组的某一段进行排序比如我们要对数组下表0-2的部分(假设数组长度大于3)进行排序,其他部分保持不变,我们可以使用:2 X `* j! `: c P. G9 W+ w
/ G$ }; U. b; | U" qArrays.sort(strArray,0,2);
, i# e2 x0 Y. h2 V这样,我们只对前三个元素进行了排序,而不会影响到后面的部分。
7 Y6 y4 ?: ?6 \0 A) s
}9 A* {1 l! F5 R2 T当然有人会想,我怎样进行降序排序?在众多的sort方法中有一个0 e3 F7 S+ [. e: E# P% ?' P
$ H: f$ x. z L- W+ Hsort(T[] a, Comparator<? super T> c) . U/ g4 U+ s, z( _& `" z5 o& ~6 [
我们使用Comparator获取一个反序的比较器即可,Comparator会在稍后讲解,以前面的intArray[]为例:+ E5 Q* e: r4 ?! Q
& P) H/ p2 g! P- M, bArrays.sort(intArray,Comparator.reverseOrder());
" q$ m4 ?) r @5 b这样,我们得到的结果就是{4,3,1,-23}。如果不想修改原有代码我们也可以使用:( O" ^" P4 P2 G& b% \
Q: s; D+ s3 [# E* u
Collections.reverse(Arrays.asList(intArray)); 9 U- m1 @6 J+ t- S
得到该数组的反序。结果同样为4,3,1,-23}。
0 i8 D; G H' v9 C+ @
+ `5 }5 p9 e6 T现在的情况变了,我们的数组里不再是基本数据类型(primtive type)或者String类型的数组,而是对象数组。这个数组的自然顺序是未知的,因此我们需要为该类实现Comparable接口,比如我们有一个Name类:& p) Z; Z% H& e1 E) }- d6 W) E
1 F# }& t# h5 B; J" P4 a; l
class Name implements Comparable<Name>{
" t5 [5 c7 W: w4 H public String firstName,lastName;
5 k4 f" S$ T) z% o$ x public Name(String firstName,String lastName){ 2 T _: M2 l4 @3 i d& L
this.firstName=firstName;
! g# x! l3 E) l' ?- M/ g/ q this.lastName=lastName; 2 ]( k4 O% Y w
}
6 O U. J; n3 k7 S, q8 M, f public int compareTo(Name o) { //实现接口
/ O" Y! z' U: [, b6 Q8 A6 T int lastCmp=lastName.compareTo(o.lastName); - P0 V; Q8 M# r' d4 x1 Q* ~& `
return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName));
5 r; o$ } B4 Q2 x4 z } 4 J+ f7 e- J: |9 ~& N0 c M
public String toString(){ //便于输出测试
( p3 L/ I, J, o& `" s return firstName+" "+lastName;
/ }7 b" J( I+ a } 2 L2 ?8 Z" V: E# X* I
} 1 K& ?3 e# c0 }) ` c$ G
这样,当我们对这个对象数组进行排序时,就会先比较lastName,然后比较firstName 然后得出两个对象的先后顺序,就像compareTo(Name o)里实现的那样。不妨用程序试一试:
) i6 o: u. H9 q4 J/ M9 G1 {4 I
( t0 m$ b: J4 M& l% e* T import java.util.*; 3 R4 N4 Q) n3 k! v9 t$ @4 p
public class NameSort {
) w* s7 Y+ z9 N& A public static void main(String[] args) { " C) @$ M* u: A( F' H0 B+ k
Name nameArray[] = { 5 n: Q! R$ j4 ?9 ^5 \# Z9 Y" L
new Name("John", "Lennon"),
2 ~" d( w2 W! c6 A new Name("Karl", "Marx"),
6 P7 z! {! r# _' g0 t new Name("Groucho", "Marx"),
; G7 L D' h* V new Name("Oscar", "Grouch")
% T* p7 d5 P$ ] ^# R( |& j# j }; |
|