TA的每日心情 | 衰 2021-2-2 11:21 |
---|
签到天数: 36 天 [LV.5]常住居民I
|
根据约定,在使用java编程的时候应尽可能的使用现有的类库,当然你也可以自己编写一个排序的方法,或者框架,但是有几个人能写得比JDK里的还要好呢?使用现有的类的另一个好处是代码易于阅读和维护,这篇文章主要讲的是如何使用现有的类库对数组和各种Collection容器进行排序,(文章中的一 部分例子来自《Java Developers Almanac 1.4》)
0 s# m7 t7 z) w0 R
8 F/ T" U5 d; F( \首先要知道两个类:java.util.Arrays和java.util.Collections(注意和Collection的区 别)Collection是集合框架的顶层接口,而Collections是包含了许多静态方法。我们使用Arrays对数组进行排序,使用 Collections对结合框架容器进行排序,如ArraysList,LinkedList等。
, c& ?' ^3 b9 V, k6 m
3 A1 i" R; C6 |0 b例子中都要加上import java.util.*和其他外壳代码,如类和静态main方法,我会在第一个例子里写出全部代码,接下来会无一例外的省略。) w f& q2 c* E+ ?9 \1 ]; Z5 r/ D0 G
* H, a: r9 ~; A对数组进行排序" e2 K' ]& d; U3 `( @( N; W
8 q$ M0 A6 S# _8 o1 u
比如有一个整型数组:
% W8 a2 h$ k# K& M5 C; \' ? t7 x+ J9 Q0 P- {8 d S T
int[] intArray = new int[] {4, 1, 3, -23}; " b2 y3 [* L) d x' x5 B, }
我们如何进行排序呢?你这个时候是否在想快速排序的算法?看看下面的实现方法:
9 m% L- r7 k$ y1 F
9 R, x# q* M0 \8 ]! q3 Yimport java.util.*;
9 q' f# |0 ~- E. B( J1 w- lpublic class Sort{ / [0 D b6 J" F9 J0 I0 F$ A% W
public static void main(String[] args){ 8 P8 @( [! U! {$ h2 W
int[] intArray = new int[] {4, 1, 3, -23}; * z# F" L1 G% s% L2 F
Arrays.sort(intArray);
4 n+ U% [+ c4 P; B+ S4 O }
$ C) m3 N3 z# h} % j' t0 |, O8 H: u
这样我们就用Arrays的静态方法sort()对intArray进行了升序排序,现在数组已经变成了{-23,1,3,4}.* C" D8 x# G* u. u. R
" w/ k) v: k1 _5 y' D* S6 f, y
如果是字符数组:
" ^/ A& z+ p' w% F! _* ]3 B6 U! e) \
String[] strArray = new String[] {"z", "a", "C"}; E; k% m% q! C' |5 O$ J7 a5 w6 v
我们用:: `5 q) _9 S8 g* L8 r, y
2 R2 _5 y/ x% Q7 j5 bArrays.sort(strArray); 3 X/ @4 l' }$ b! @; l
进行排序后的结果是{C,a,z},sort()会根据元素的自然顺序进行升序排序。如果希望对大小写不敏感的话可以这样写:" @6 z8 K% n! d/ {* L
8 J3 Z$ W( y! o w/ pArrays.sort(strArray, String.CASE_INSENSITIVE_ORDER);
; n$ x. o" \& L! s/ h0 S: f当然我们也可以指定数组的某一段进行排序比如我们要对数组下表0-2的部分(假设数组长度大于3)进行排序,其他部分保持不变,我们可以使用:
3 j% c u1 Z* O& U- n: |8 O* C4 G1 M. s& [" h
Arrays.sort(strArray,0,2); . ]$ F/ e4 q! C- A6 i; X4 a s
这样,我们只对前三个元素进行了排序,而不会影响到后面的部分。
+ f% Q2 k* S% x6 |7 }5 V/ Q4 s! B' _. t) |9 C5 Q
当然有人会想,我怎样进行降序排序?在众多的sort方法中有一个
& L. I9 H; t, Y4 E& B2 p/ I: N" Y9 X& A6 b& d7 C% P
sort(T[] a, Comparator<? super T> c)
# R3 @) i6 x( `) ^2 \6 |我们使用Comparator获取一个反序的比较器即可,Comparator会在稍后讲解,以前面的intArray[]为例:
6 N6 ~8 Z, w7 l4 _/ S7 `& }% h4 R* }! l$ N2 A# H
Arrays.sort(intArray,Comparator.reverseOrder()); 0 Z" |5 m) L6 W' [
这样,我们得到的结果就是{4,3,1,-23}。如果不想修改原有代码我们也可以使用:
' F7 _: v, x) q5 \8 o3 o5 C9 n, H2 `: e
Collections.reverse(Arrays.asList(intArray));
6 T7 T8 ]6 D2 G; H得到该数组的反序。结果同样为4,3,1,-23}。
* @1 W; P( j5 |+ T1 t# H% n
8 l- e, T# y8 U, L) s6 V# N现在的情况变了,我们的数组里不再是基本数据类型(primtive type)或者String类型的数组,而是对象数组。这个数组的自然顺序是未知的,因此我们需要为该类实现Comparable接口,比如我们有一个Name类:
5 V" S& o0 {8 e- O7 k
9 E4 f* _. V& E" ~1 k) xclass Name implements Comparable<Name>{
" `) ] H6 D; G# {* H/ y public String firstName,lastName;
1 e0 C, ^+ _" W6 D4 T# I" w- \3 F public Name(String firstName,String lastName){ + P% {# R, ?4 I: b$ W2 L) l% h$ Q. ^; x, D
this.firstName=firstName;
' t( W( |; Q+ x. A$ e0 g, i this.lastName=lastName; . W5 s; v3 l/ X! h! C2 B
} - K* d, U9 ~2 B& f3 R* r% d& I j3 A
public int compareTo(Name o) { //实现接口
2 I' J6 E4 i8 r* P u" B int lastCmp=lastName.compareTo(o.lastName);
/ ]) A' D9 p8 }/ t+ p/ K, x return (lastCmp!=0?lastCmp:firstName.compareTo(o.firstName)); : j7 C& i3 l( j1 h' a
} / V0 l6 g, N" W$ _2 Y1 Z1 J" ]
public String toString(){ //便于输出测试 2 \" u1 l8 {7 A# c6 ~, s2 b
return firstName+" "+lastName;
9 M$ X- K r+ R% }- O' `* z }
: d# X8 A( I8 F( z# U} z$ m: X: [& D) D8 i! C
这样,当我们对这个对象数组进行排序时,就会先比较lastName,然后比较firstName 然后得出两个对象的先后顺序,就像compareTo(Name o)里实现的那样。不妨用程序试一试:
5 Q3 Z3 v7 j8 t8 f: l6 N4 ^! @$ T2 D
import java.util.*;
9 _1 _* ^; n0 u) V9 d6 [ public class NameSort {
' V3 [; L6 R' H0 Y& |" H( n- B public static void main(String[] args) {
9 A, Y# E! B, L Name nameArray[] = { & r) X M9 R- w' j6 E6 P2 I
new Name("John", "Lennon"), " N, J! w9 t( R7 ]9 R& b3 S
new Name("Karl", "Marx"),
) n& U* A; g* ]9 P: l( L6 e new Name("Groucho", "Marx"), # n* x y& X* r- e
new Name("Oscar", "Grouch")
$ _( o2 k) n. a }; |
|