TA的每日心情 | 衰 2021-2-2 11:21 |
|---|
签到天数: 36 天 [LV.5]常住居民I
|
根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还要好呢?使用现有的类的另一个好处是代码易于阅读和维护,这篇文章主要讲的是如何使用现有的类库对数组和各种Collection容器进行排序,(文章中的一 部分例子来自《Java Developers Almanac 1.4》)
7 L) r* F% M! ?8 @" y
1 r) A. z6 s1 H- O7 g6 i首先要知道两个类:java.util.Arrays和java.util.Collections(注意和Collection的区 别)Collection是集合框架的顶层接口,而Collections是包含了许多静态方法。我们使用Arrays对数组进行排序,使用 Collections对结合框架容器进行排序,如ArraysList,LinkedList等。
& M3 M8 \6 w/ s/ V& h
% c5 K+ n; ^# c例子中都要加上import java.util.*和其他外壳代码,如类和静态main方法,我会在第一个例子里写出全部代码,接下来会无一例外的省略。# A4 p5 l( h ?, i& U" o
H+ y. v2 O1 [对数组进行排序
5 d: u0 t1 l, b j
6 S6 I: I( R3 c! O* Y9 i# A比如有一个整型数组:# `0 d0 {& G; q% ?* _0 R ^
) B% d; E' S& f. G6 W# rint[] intArray = new int[] {4, 1, 3, -23}; % T' o) z1 U3 o; `9 z
我们如何进行排序呢?你这个时候是否在想快速排序的算法?看看下面的实现方法:0 v6 q7 N( s4 T; P3 i
M% [' x ^# [- E6 x
import java.util.*;
! c* |* }( i4 ?) G9 t' X ~. s H6 Ypublic class Sort{ C5 f. s) M+ C+ s
public static void main(String[] args){
" w/ f8 @7 C, E4 k7 l6 j" W int[] intArray = new int[] {4, 1, 3, -23};
, Y7 l- v8 h+ J0 c8 j O, L Arrays.sort(intArray); ( Y7 E2 l8 }) a+ Q8 i3 _! ]
}
: _- S- [- z' \4 I# \: z. p. q} ( v4 n" N* F- j5 m! j
这样我们就用Arrays的静态方法sort()对intArray进行了升序排序,现在数组已经变成了{-23,1,3,4}.9 |) L2 g- {+ ?+ c
1 p- H0 C& }1 n' f7 M3 M* `& k/ G如果是字符数组:, t0 [$ ^1 X/ t4 l4 o
" {' m: t8 s5 Q, P
String[] strArray = new String[] {"z", "a", "C"}; ; @8 a& f6 _6 Y# g
我们用:9 }( i* Z: R* z: ~
6 H" w6 p" W9 y9 c$ S8 ^ h3 w MArrays.sort(strArray);
1 o' |6 C" R, B7 C* ~1 q/ G# S进行排序后的结果是{C,a,z},sort()会根据元素的自然顺序进行升序排序。如果希望对大小写不敏感的话可以这样写:
2 O# c$ |$ O# v' s4 V. ]( r& B9 e: v9 \" }% D4 |7 H2 |4 ]
Arrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);
1 d+ b* i& ^3 t' f, }6 y当然我们也可以指定数组的某一段进行排序比如我们要对数组下表0-2的部分(假设数组长度大于3)进行排序,其他部分保持不变,我们可以使用:; T; s* f: T3 Q6 ^8 r* Z
! I+ Q2 K+ ?% P* }Arrays.sort(strArray,0,2); * a& y! M* [4 H+ _& w" G
这样,我们只对前三个元素进行了排序,而不会影响到后面的部分。
) p" ^6 I2 f9 f6 N* V6 r3 C1 C; ]- e/ v2 B
当然有人会想,我怎样进行降序排序?在众多的sort方法中有一个8 v- H: a3 Q/ i
8 z/ N6 t& I4 W/ U$ j. S6 i
sort(T[] a, Comparator<? super T> c)
1 B# y+ o m: `4 h% C我们使用Comparator获取一个反序的比较器即可,Comparator会在稍后讲解,以前面的intArray[]为例:
0 V- Q7 \4 M! f& R0 [
( ~5 a) Y2 C' [6 T( nArrays.sort(intArray,Comparator.reverseOrder()); 5 T. y7 `7 N9 c( t( E5 [$ W
这样,我们得到的结果就是{4,3,1,-23}。如果不想修改原有代码我们也可以使用:
) w: Y* f/ L/ t H- c6 {3 Q5 o8 a) ^* T# O: t3 ?; G2 U
Collections.reverse(Arrays.asList(intArray));
: v; _ s7 K& w得到该数组的反序。结果同样为4,3,1,-23}。
4 l, O9 Z& W' H$ c: u& n, S+ }4 M" h( p" l! [; O6 J. s7 k
现在的情况变了,我们的数组里不再是基本数据类型(primtive type)或者String类型的数组,而是对象数组。这个数组的自然顺序是未知的,因此我们需要为该类实现Comparable接口,比如我们有一个Name类:0 M; W2 P0 }, @$ c# I
+ n$ X" [) a. _. C* xclass Name implements Comparable<Name>{ 4 j1 o7 l! x% N# q
public String firstName,lastName; & m: Q( J: W% e2 j, ^
public Name(String firstName,String lastName){
* {+ L7 t6 x/ j8 v6 i/ e this.firstName=firstName;
5 ^1 T" E4 Q1 ]! U6 A" ~ this.lastName=lastName; + f" v: a5 W* J& p" J! K
}
6 V9 S9 C8 M% e( ] public int compareTo(Name o) { //实现接口 6 Z6 O$ d+ G& ~) E
int lastCmp=lastName.compareTo(o.lastName);
/ p. V5 n7 |2 f' F7 L return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName));
& Y+ P- C6 Z- s9 O) \ } " H$ J" V# P# o+ ]3 M( M0 v
public String toString(){ //便于输出测试 0 p ~1 l q5 z% D4 l2 }4 v
return firstName+" "+lastName;
5 Z, }8 `/ X5 x: e, c } + {% R; N/ a( P; s
}
8 \& _7 e! w. a, N这样,当我们对这个对象数组进行排序时,就会先比较lastName,然后比较firstName 然后得出两个对象的先后顺序,就像compareTo(Name o)里实现的那样。不妨用程序试一试:
+ ?! g5 ?6 n. A. n; I1 r5 U5 b9 {# k8 B4 B) E
import java.util.*; ( Y# z/ |( ~7 I8 i; v
public class NameSort {
: t0 v- a7 T1 p; g; M+ r/ N) ]2 j public static void main(String[] args) { # P- @( P6 A$ N4 |8 F7 v, F& p
Name nameArray[] = { 7 P a6 N+ F6 N1 {& a. m: F0 w
new Name("John", "Lennon"),
# ]: ^( p! f0 Y4 a3 q O new Name("Karl", "Marx"),
1 f8 i* o0 [# Y' r1 V new Name("Groucho", "Marx"),
8 ]% K2 v- d, p- p& P" C new Name("Oscar", "Grouch") 5 d) \* S+ u$ k1 I
}; |
|