TA的每日心情 | 衰 2021-2-2 11:21 |
|---|
签到天数: 36 天 [LV.5]常住居民I
|
根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还要好呢?使用现有的类的另一个好处是代码易于阅读和维护,这篇文章主要讲的是如何使用现有的类库对数组和各种Collection容器进行排序,(文章中的一 部分例子来自《Java Developers Almanac 1.4》)+ E: \4 M- w( D, W0 k2 {
9 n8 l$ i5 a* z" {首先要知道两个类:java.util.Arrays和java.util.Collections(注意和Collection的区 别)Collection是集合框架的顶层接口,而Collections是包含了许多静态方法。我们使用Arrays对数组进行排序,使用 Collections对结合框架容器进行排序,如ArraysList,LinkedList等。
7 F2 F5 ~5 N# B; I7 n/ u& i0 e* I8 q4 N7 R/ ?' p- j! U* F2 k
例子中都要加上import java.util.*和其他外壳代码,如类和静态main方法,我会在第一个例子里写出全部代码,接下来会无一例外的省略。
N& m3 T& c; Q( p# G. O. ?% T0 ]' u* z9 o6 a
对数组进行排序
2 z7 e1 O6 n3 G. ~, Y7 _
4 J0 j- j z2 u% u9 f比如有一个整型数组:5 b. A, ~$ N$ \# U2 M' c$ v
; }3 S" `7 t* d& Eint[] intArray = new int[] {4, 1, 3, -23};
$ d/ {' `, ^* P- Q7 E* ]5 t* `5 g我们如何进行排序呢?你这个时候是否在想快速排序的算法?看看下面的实现方法:- {+ d$ b* |& I; L: [! T
' t; B: s6 ^( Q4 h
import java.util.*; ( g! e3 t3 `7 a% a* s, d9 t
public class Sort{
" z/ `' E+ N8 Q4 n0 L) m1 H/ \ public static void main(String[] args){
9 g7 _1 V1 E/ a1 @( B: ] int[] intArray = new int[] {4, 1, 3, -23}; ' N& x4 g7 l! E1 d0 z5 B
Arrays.sort(intArray); * [# C/ b% G( r. ^) W
} ' @# o, _" x$ c9 L. E+ c
} ( o/ I, H9 ]5 C
这样我们就用Arrays的静态方法sort()对intArray进行了升序排序,现在数组已经变成了{-23,1,3,4}.1 s7 }/ O% L1 g% G+ P
! @7 D/ P( a# d
如果是字符数组:
, g k1 s2 M4 ^# n5 v, x- d
# ~0 N3 p' U1 o: M0 K- ]String[] strArray = new String[] {"z", "a", "C"}; ; ]5 b* ?! e: G# D
我们用:) i5 o7 w5 D% [( `/ M
& O C8 \. m9 j- u( ?; s. I0 ~
Arrays.sort(strArray);
; G3 B% c n* S/ S+ z进行排序后的结果是{C,a,z},sort()会根据元素的自然顺序进行升序排序。如果希望对大小写不敏感的话可以这样写:
* A6 N6 }/ i1 ~ Z4 }6 F. S. l6 ?; F5 f
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER); 2 G5 p) C' G" B( H: ]
当然我们也可以指定数组的某一段进行排序比如我们要对数组下表0-2的部分(假设数组长度大于3)进行排序,其他部分保持不变,我们可以使用:
( h1 f7 l; B* M6 [
/ S Y! v5 z/ tArrays.sort(strArray,0,2);
; n7 Y2 U$ f* E) Z7 O1 o/ m9 D这样,我们只对前三个元素进行了排序,而不会影响到后面的部分。9 Z# A6 }# `9 `% U, [: G
* F) h' ?9 E, B8 E/ ~4 n6 A2 z当然有人会想,我怎样进行降序排序?在众多的sort方法中有一个
! f6 I" r2 y' ?, J. m8 t% j$ k5 Z! N
sort(T[] a, Comparator<? super T> c)
8 s* t# I/ [. U6 k/ L1 _( z8 F我们使用Comparator获取一个反序的比较器即可,Comparator会在稍后讲解,以前面的intArray[]为例:0 O8 L/ H/ l4 j
; Y2 n) R% b0 F6 fArrays.sort(intArray,Comparator.reverseOrder());
9 y( ^( y6 u# g' P, {% ~# Q这样,我们得到的结果就是{4,3,1,-23}。如果不想修改原有代码我们也可以使用:. z! ^" l4 A+ ]+ U, Y9 q7 b& U
8 P1 b5 f7 P' S5 e) `' q0 d
Collections.reverse(Arrays.asList(intArray)); * X! g2 m8 T5 Z8 W: X
得到该数组的反序。结果同样为4,3,1,-23}。( T7 K/ {8 n- j) r" Q
! U4 W. _; K* s7 y! a6 U现在的情况变了,我们的数组里不再是基本数据类型(primtive type)或者String类型的数组,而是对象数组。这个数组的自然顺序是未知的,因此我们需要为该类实现Comparable接口,比如我们有一个Name类:7 w1 p8 Z5 H+ o! Y
0 R( r* c _$ @- P
class Name implements Comparable<Name>{
1 g% R9 Z$ G7 T* r, L* ^ public String firstName,lastName;
0 H% F% Z& w4 Q* j( U% P# l public Name(String firstName,String lastName){ & D! s2 t% l. T. c
this.firstName=firstName;
4 V1 b1 I+ T' w this.lastName=lastName; 8 o; F f% l2 b; ^$ I
} $ g6 Z8 W6 |2 }- C, G/ ^+ y+ m
public int compareTo(Name o) { //实现接口
' U! F8 j8 b# s4 _, l1 n1 |8 R; E6 P( r int lastCmp=lastName.compareTo(o.lastName); 6 [2 k. D. P2 {2 H2 ?. G
return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName)); 5 n$ Z, e8 X& u% Y# d
}
7 a. n/ u' I, I- x' K+ M$ x public String toString(){ //便于输出测试
. O7 G; D" y) P; Q1 `5 i return firstName+" "+lastName;
2 |7 l; Q Q/ M3 b/ D }
5 _8 Z' B. N( ^5 \}
9 o9 @! P- y5 T这样,当我们对这个对象数组进行排序时,就会先比较lastName,然后比较firstName 然后得出两个对象的先后顺序,就像compareTo(Name o)里实现的那样。不妨用程序试一试:
2 J( a# p4 O. C+ Y- I! b! ^$ e5 K; q& p* n
import java.util.*;
. T% G) P( Y; }& Z* X$ h( p' E public class NameSort { , L8 O3 E8 W$ s( E, y
public static void main(String[] args) {
]+ i7 V4 B4 J: ? Name nameArray[] = { ) X9 I5 d! X2 s' r2 e
new Name("John", "Lennon"), . x6 S6 ?9 ?0 L+ l. t p' |
new Name("Karl", "Marx"),
* S9 {1 B" ]! S2 e; R new Name("Groucho", "Marx"), t( x& y7 r! w+ A# u$ }
new Name("Oscar", "Grouch") . [' F# G6 c; p8 ?# b9 w4 S
}; |
|