Java编程手册-Collection框架(上)

来源:互联网 发布:java简单项目 编辑:程序博客网 时间:2024/05/16 15:34

该文章所讲内容基本涵盖了Collection里面的所有东西,虽然基于jdk 1.5的,但是思路很清晰

1.引言
1.1 Collection框架的介绍

虽然我们可以使用数组去存储具有相同类型的元素集合(包括基本类型和对象类型),但是数组不支持所谓的动态内存分配,一旦分配之后,它的长度就是固定的,无法改变,另外,数组是一个简单的线性结构,在我们的实际开发中,可能会需要更复杂的数据结构,例如linked list, stack, hash table, sets, 或者 trees.

在Java中,有统一的Collection框架来支持这种动态分配的数据结构(例如:ArrayList, LinkedList, Vector, Stack, HashSet, HashMap, Hashtable),它通过接口统一了所有继承类的基本操作,形成了一套基本的体系。

Java集合框架包(java.util)里包含下面内容:

1、接口集合
2、类实现
3、算法(例如排序和查找)

1.2 Colloction例子— ArrayList (Pre-JDK 1.5)

ArrayList是一个线性的数据结构,类似于数组,但是它是可伸缩的。下面使用了ArrayList来存放String集合对象。

// Pre-JDK 1.5import java.util.List;import java.util.ArrayList;import java.util.Iterator; public class ArrayListPreJDK15Test {   public static void main(String[] args) {      List lst = new ArrayList();  // A List contains instances of Object. Upcast ArrayList to List      lst.add("alpha");            // add() takes Object. String upcast to Object implicitly      lst.add("beta");      lst.add("charlie");      System.out.println(lst);     // [alpha, beta, charlie]       // Get a "iterator" instance from List to iterate thru all the elements of the List      Iterator iter = lst.iterator();      while (iter.hasNext()) {      // any more element         // Retrieve the next element, explicitly downcast from Object back to String         String str = (String)iter.next();         System.out.println(str);      }   }}

程序分析

  • 2-4行引入了java.util包中集合框架的类和接口


上图可以看到ArrayList的继承关系,我们可以看到ArrayList实现了List, Collection 和 Iterable接口,Collection和Iterable接口定义了所有集合都需要实现的基本操作。Collection接口定义了如何添加和移除一个元素。Iterable接口定义了一种机制去遍历集合中的所有元素。一般不直接使用Collection接口,而是使用它的子接口List(支持索引访问的有序列表)、Set(不允许元素的重复)、Queue(先进先出)。

  • 在第8行中,创建了一个ArrayList实例,并将它向上转换为List接口,因为ArrayList实现了List接口,一般比较良好的编程操作都是在接口上面,而不是在它的实现上面。Collection框架提供了一个接口集合,这样你可以使用这些接口而不是它的实现。
  • Collection接口定义了一些对基本的操作方法。
// Pre-JDK 1.5boolean add(Object element)     // adds an elementboolean remove(Object element)  // removes an elementint size()                      // returns the sizeboolean isEmpty()               // checks if empty</span>
可以看到,在pre-JDK 1.5上,add(Object)方法操作的是Object对象,Object类是所有类的超类,因此,所有类都是Object类的子类,任何Java类都可以向上转换为Object类,然后添加到集合中,并且这个转换是编译器隐式操作的,它是类型安全的。
  • Iterable接口包含一个抽象方法去获取集合所关联的Iterator对象,这样通过Iterator对象就可以遍历整个集合。
Iterator iterator();   // returns an Iterator object to iterate thru all the elements of the collection
  • Iterator声明了下面的抽象方法进行集合遍历
// Pre-JDK 1.5boolean hasNext()  // returns true if it has more elementsObject next()      // returns the next elementvoid remove()      // removes the last element returned by the iterator</span>
  • 第15-20行获取ArrayList相关联的Iterator对象,并且使用while循环来遍历集合。
  • 在18行,iter.next() 方法方法返回的是Object类型的对象,这个在上面add(Object)中说过,我们在得到Object类型的对象之后,需要显式的将类型转换为String类型,因为编译器不知道我们需要的具体类型。
  • 其实我们也可以使用LinkedList, Vector 和 Stack,并且只需要修改第8行的实例化代码即可,其他不变,这也可以看出接口的统一性,虽然实现不同,但是操作的效果相同。
List lst = new LinkedList();   // use "LinkedList" implementation// orList lst = new Vector();       // use "Vector" implementation// orList lst = new Stack();        // use "Stack" implementation

1.3  Pre-JDK 1.5 Collections不是类型安全的

Pre-JDK 1.5存在下面的缺陷:
1、编译器会将元素隐式地向上转换为java.lang.Object,但是当我们获取元素的时候,我们获取的就是java.lang.Object类型的对象,我们需要显式的将它向下转换为我们的原始类型。
2、编译器不能在编译时检查向下转换的有效性,错误的向下转换会在运行是抛出ClassCastException异常。
这两个问题其实在上面代码的分析过程中也说到过,缺陷也很明显。
// lst is designed to hold Stringslst.add(new Integer(88));  // adds an Integer, implicitly upcast to Object, okay in compile/runtime Iterator iter = lst.iterator();while (iter.hasNext()) {   String str = (String)iter.next(); // compile okay but runtime ClassCastException   System.out.println(str);}

1.4 JDK 1.5中引入泛型

针对上面的缺陷,JDK 1.5中引入了一个新的特性——泛型,它可以传递类型信息,这样编译器在编译的过程中可以进行必要的类型检查,这样就避免的运行是类型安全问题。
List<String> lst = new ArrayList<String>();  // read as List of Strings, ArrayList of Strings
上面我们传递了一个String类型,在ArrayList内部的操作使用的就是String类型,避免了类型的转换,如果添加其他类型的元素,编译器就会报错。

1.5 带有泛型的ArrayList
// Post-JDK 1.5 with Genericsimport java.util.List;import java.util.ArrayList;import java.util.Iterator; public class ArrayListPostJDK15Test {   public static void main(String[] args) {      List<String> lst = new ArrayList<String>();  // Inform compiler about the type      lst.add("alpha");         // compiler checks if argument's type is String      lst.add("beta");      lst.add("charlie");      System.out.println(lst);  // [alpha, beta, charlie]       Iterator<String> iter = lst.iterator();   // Iterator of Strings      while (iter.hasNext()) {         String str = iter.next();  // compiler inserts downcast operator         System.out.println(str);      } //      lst.add(new Integer(1234));   // ERROR: compiler can detect wrong type//      Integer intObj = lst.get(0);  // ERROR: compiler can detect wrong type       // Enhanced for-loop (JDK 1.5)      for (String str : lst) {         System.out.println(str);      }   }}

可以看到,使用泛型之后,就基本不存在前面所说隐式和显式类型转换了,因为内部使用的就是我们传递进去的类型,而不是上面所说的Object类型,如果添加其他类型的话,编译器就会报错。

1.6 向后兼容
JDK 1.5是兼容pre-JDK 1.5的使用的。例如在JDK 1.5中使用pre-JDK 1.5的用法,仍然是可以执行的,只是同样没有类型检查。
// Pre-JDK 1.5List lst = new ArrayList();  // No type informationlst.add("alpha");   // Without generics, compiler can't check if the type is correct

1.7 自动装箱和自动拆箱(JDK 1.5)
一个集合只能存放对象,它不能包含基本数据类型,例如int或者double,这就存在问题了,尽管数组可以存放基本数据类型,但是前面说过它是不可扩展的。所以如果希望在集合中存放基本数据类型,就必须使用对应的包装类把基本数据类型包装成对应类型的对象,下面这副图对应的就是基本数据类型与对象类型的对应关系。



在JDK 1.5之前,向集合添加元素,必须将基本数据类型包装为对应的对象类型,从集合获取元素,必须把对应对象类型拆解为对应的基本数据类型。
// Pre-JDK 1.5Integer intObj = new Integer(5566);    // wrap int to Integerint i = intObj.intValue();             // unwrap Integer to int Double doubleObj = new Double(55.66);  // wrap double to Doubledouble d = doubleObj.doubleValue();    // unwrap Double to double

从上面可以看到,在JDK 1.5之前,装箱和解箱操作需要我们自己手动去完成,JDK 1.5就针对这一问题,提出了一个新特性,就是自动装箱与解箱。也就是本来需要我们手工完成的事情,编译器帮助我们完成了。
// JDK 1.5Integer intObj = 5566;    // autobox from int to Integerint i = intObj;           // auto-unbox from Integer to int Double doubleObj = 55.66; // autoboxing from double to Doubledouble d = doubleObj;     // atuo-unbox from Double to double

例子—Pre JDK 1.5中集合
Pre JDK 1.5不支持泛型、自动装箱与解箱和for-each循环,下面的代码就显得混乱并且不是类型安全的。
// Pre-JDK 1.5import java.util.List;import java.util.ArrayList;import java.util.Iterator;import java.util.Random; public class PrimitiveCollectionPreJDK15 {   public static void main(String[] args) {      List lst = new ArrayList();       // Add 10 random primitive int into the List      Random random = new Random();      for (int i = 1; i <= 10; ++i) {         // Wrap the primitive int into Integer, upcast to Object         lst.add(new Integer(random.nextInt(10)));      }      System.out.println(lst);       Iterator iter = lst.iterator();      while (iter.hasNext()) {         // Explicit downcast to Integer, then unwrap to int         int i = ((Integer)iter.next()).intValue();   // un-safe at runtime         System.out.println(i);      }   }}

例子—Post-JDK 1.5中的集合
在JDK1.5之后,就支持了泛型、自动装箱与解箱以及for-each循环,代码会更加简洁并且是类型安全的。
// Post-JDK 1.5import java.util.List;import java.util.ArrayList;import java.util.Iterator;import java.util.Random; public class PrimitiveCollectionJDK15 {   public static void main(String[] args) {      List<Integer> lst = new ArrayList<Integer>();       // Add 10 random primitive int into the List      Random random = new Random();      for (int i = 1; i <= 10; ++i) {         lst.add(random.nextInt(10)); // autobox to Integer, upcast to Object, type-safe      }      System.out.println(lst);       // Transverse via iterator      Iterator<Integer> iter = lst.iterator();      while (iter.hasNext()) {         int i = iter.next();  // downcast to Integer, auto-unbox to int, type-safe         System.out.println(i);      }       // Transverse via enhance for-loop      for (int i : lst) {      // downcast to Integer, auto-unbox to int, type-safe         System.out.println(i);      }       // Retrieve via for-loop with List's index      for (int i = 0; i < lst.size(); ++i) {         int j = lst.get(i);   // downcast to Integer, auto-unbox to int, type-safe         System.out.println(j);      }   }}

2. Collection接口
下图是Collection框架中的接口和常用实现类


2.1  Iterable<E>接口

Iterable<E>接口,它包含了一个泛型类型E,E对应的就是集合元素类型,这个接口声明了一个抽象方法iterator() 用来获取一个Iterator<E>对象,Iterator用来遍历它所关联集合的所有元素。

Iterator<E> iterator();   // Returns the associated Iterator instance                           // that can be used to transverse thru all the elements of the collection
所有Collection的实现(例如:ArrayListLinkedListVector必须实现这个方法,并且返回的对象也实现了Iterator接口。

2.2  Iterator<E>接口

Iterator<E>接口声明了下面三个抽象方法。

boolean hasNext()  // Returns true if it has more elementsE next()           // Returns the next element of generic type Evoid remove()      // Removes the last element returned by the iterator

我们可以使用Iterator和一个while循环进行集合的遍历

List<String> lst = new ArrayList<String>();lst.add("alpha");lst.add("beta");lst.add("charlie"); // Retrieve the Iterator associated with this List via the iterator() methodIterator<String> iter = lst.iterator();// Transverse thru this List via the Iteratorwhile (iter.hasNext()) {   // Retrieve each element and process   String str = iter.next();   System.out.println(str);}

2.3 加强版的for循环 (JDK 1.5)

对于使用Iterator进行集合的遍历,在JDK 1.5中引入了新的加强版的for循环,使用它进行集合的遍历更加方便。

下面是基本的用法

for ( type item : aCollection ) {   body ;}

可以在集合中修改对象吗?

加强版的for循环提供了一个方便的方法去遍历集合元素,但是它将Iterator给隐藏了,因此你不能移除或者替换这个元素。循环变量接受的是一个引用的副本,因此这个加强版的for循环可以通过该引用修改对应的可变元素(例如:StringBuilder),但是不能修改不可变元素(例如:String和基本数据类型对应的对象类型)。

例子——使用加强版的for循环对于集合的可变元素(例如:StringBuilder

import java.util.List;import java.util.ArrayList; public class ForEachMutableTest {   public static void main(String[] args) {      List<StringBuilder> lst = new ArrayList<StringBuilder>();      lst.add(new StringBuilder("alpha"));      lst.add(new StringBuilder("beta"));      lst.add(new StringBuilder("charlie"));      System.out.println(lst);   // [alpha, beta, charlie]       for (StringBuilder sb : lst) {         sb.append("88");   // can modify "mutable" objects      }      System.out.println(lst);  // [alpha88, beta88, charlie88]   }}

例子——使用加强版的for循环对于集合的不可变元素(例如:StringBuilder

import java.util.List;import java.util.ArrayList; public class ForEachImmutableTest {   public static void main(String[] args) {      List<String> lst = new ArrayList<String>();      lst.add("alpha");      lst.add("beta");      lst.add("charlie");      System.out.println(lst);   // [alpha, beta, charlie]       for (String str : lst) {         str += "change!";   // cannot modify "immutable" objects      }      System.out.println(lst);   // [alpha, beta, charlie]   }}

2.4  Collection<E>接口

    Collection<E>包含一个泛型类型E,E是集合的元素数据类型,并且Collection<E>是集合框架的超类,它包含了其他类都需要实现的基本操作,例如:

// Basic Operationsint size()                        // Returns the number of elements of this Collectionvoid clear()                      // Removes all the elements of this Collectionboolean isEmpty()                 // Returns true if there is no element in this Collectionboolean add(E element)            // Ensures that this Collection contains the given elementboolean remove(Object element)    // Removes the given element, if presentboolean contains(Object element)  // Returns true if this Collection contains the given element// Bulk Operations with another Collectionboolean containsAll(Collection<?> c)       // Collection of any "unknown" objectboolean addAll(Collection<? extends E> c)  // Collection of E or its sub-typesboolean removeAll(Collection<?> c)boolean retainAll(Collection<?> c) // Comparison - Objects that are equal shall have the same hashCodeboolean equals(Object o)int hashCode() // Array OperationsObject[] toArray()       // Convert to an Object array<T> T[] toArray(T[] a)   // Convert to an array of the given type T

 Collection<E>中只能包含对象类型,不能包含基本数据类型(例如:int和double),所以如果需要将基本数据类型包装成对应的对象类型,JDK 1.5引入了自动拆箱和解箱操作来解决这个问题,这个在前面已经讲过。

2.5  List<E>, Set<E> & Queue<E> — Collection<E>的子接口

在实际开发过程中,我们一般使用Collection的子类接口——List<E>Set<E>, 和 Queue<E>,它们提供了更多其他的特性。

  • List<E>:它相当于一个可扩展的线性数组,可以进行索引访问,并且可以包含重复的元素,我们经常会使用到的一些List的实现类为: ArrayListLinkedListVector 和 Stack。
  • Set<E>:相当于一个数据集合,它不能包含重复的元素,经常使用到的Set的实现类为:HashSet和 LinkedHashSet,子接口为SortedSet<E> 是一个有序的元素集合,TreeSet是SortedSet<E> 的实现类。
  • Queue<E>: 相当于一个先进先出的队列,它的子接口Deque<E>相当于一个可在两端操作的双向队列,实现类为PriorityQueueArrayDeque 和 LinkedList。
2.6  Map<K,V>接口
接口Map<K,V>包含了两个泛型类型K和V,它们组成一个键值对,Map就是一个键值对的集合,键值key是不允许重复的,经常使用到的实现类为HashMapHashtable 和 LinkedHashMap,它的子接口 SortedMap<K, V> 表示一个基于键值key有序的键值对集合,实现类为TreeMap。

需要注意的是,Map<K,V>不是Collection<E>的子接口。

3. List<E>接口与实现
    在实际的编程中,我们更多使用的是Collection的子接口ListSet, 和 Queue来代替Collection接口,这些子接口只是对Collection接口操作的重新定义。
    List<E>相当于一个可扩展的线性数组,它支持索引访问,它可以包含重复的元素,也可以包含null元素。


List<E> 父接口的基础上,List<E> 也声明了一些抽象方法。
// Operations at a specified index positionvoid add(int index, E element)    // addE set(int index, E element)       // replaceE get(int index)                  // retrieve without removeE remove(int index)               // remove last retrievedint indexOf(Object obj)int lastIndexOf(Object obj)// Operations on a range fromIndex (inclusive) toIndex (exclusive)List<E> subList(int fromIndex, int toIndex)...... // Operations inherited from Collection<E>int size()boolean isEmpty()boolean add(E element)boolean remove(Object obj)boolean contains(Object obj)void clear();......

抽象类AbstractList提供了很多List、Collector和Iterable接口中声明的抽象方法的实现,另外有些方法仍然是抽象的,这些方法会被子类实现,例如ArrayList 和 Vector。

3.1  ArrayList<E> & Vector<E> —— List<E>的实现类
    ArrayList<E>是List接口全面的实现类,很多有用的方法已经被AbstractList实现,但是ArrayList也进行了重写。ArrayList不是线程同步的,因此它不是线程安全的。
   Vector是JDK 1.0中遗留的类,在JDK 1.2中将它更新到了Collection中,它是List接口的一个线程同步(线程安全)的实现,包含了很多遗留的方法(例如:addElement()removeElement()setElement()elementAt()firstElement()lastElement()insertElementAt()),毫无疑问,这些遗留的方法是可以使用的,并且保持向后兼容。
   需要注意的是,虽然ArrayList<E>不是线程安全的,而Vector是线程安全的,但是ArrayList<E>显然比Vector有更好的性能。

3.2  Stack<E>——List<E>的实现类
    Stack<E>是一个后进先出的队列,它扩展于Vector,它是一个同步的可扩展的数组,也就是它是线程安全的,包含了下面方法。
E push(E element)       // pushes the specified element onto the top of the stackE pop()                 // removes and returns the element at the top of the stackE peek()                // returns the element at the top of stack without removingboolean empty()         // tests if this stack is emptyint search(Object obj)  // returns the distance of the specified object from the top                        //  of stack (distance of 1 for TOS), or -1 if not found

3.3  LinkedList<E> - List<E>的实现类

    LinkedList<E>是一个双向链表,它实现了List<E>接口,在元素的插入和删除上,效率更高,但是浪费了更多复杂的结构。
    LinkedList<E> 也实现了Queue<E> 和 Deque<E>,因此它可以充当FIFO 和 LIFO队列。

3.4 转换一个List为一个数组 - toArray()
在超类接口Collection中定义了一个toArray()方法,它可以使用该列表来创建一个数组,返回的数组可以进行自由的修改。
Object[] toArray()      // Object[] version<T> T[] toArray(T[] a)  // Generic type version

例子:
import java.util.List;import java.util.ArrayList;import java.util.Arrays;public class TestToArray {   public static void main(String[] args) {      List<String> lst = new ArrayList<String>();      lst.add("alpha");      lst.add("beta");      lst.add("charlie");       // Use the Object[] version      Object[] strArray1 = lst.toArray();      System.out.println(Arrays.toString(strArray1));   // [alpha, beta, charlie]       // Use the generic type verion - Need to specify the type in the argument      String[] strArray2 = lst.toArray(new String[0]);      strArray2[0] = "delta";   // modify the returned array      System.out.println(Arrays.toString(strArray2));   // [delta, beta, charlie]      System.out.println(lst);  // [alpha, beta, charlie] - no change in the original list   }}

3.5 将数组转换为一个List - Arrays.asList()

工具类java.util.Arrays提供了静态方法Arrays.asList()可以将数组转换为List<T>,但是,如果修改了List里面的元素内容,数组中相应的元素内容也会改变,反之亦然。

例子:
import java.util.List;import java.util.ArrayList;import java.util.Arrays;public class TestArrayAsList {   public static void main(String[] args) {      String[] strs = {"alpha", "beta", "charlie"};      System.out.println(Arrays.toString(strs));   // [alpha, beta, charlie]       List<String> lst = Arrays.asList(strs);      System.out.println(lst);  // [alpha, beta, charlie]       // Changes in array or list write thru      strs[0] += "88";      lst.set(2, lst.get(2) + "99");      System.out.println(Arrays.toString(strs)); // [alpha88, beta, charlie99]      System.out.println(lst);  // [alpha88, beta, charlie99]       // Initialize a list using an array      List<Integer> lstInt = Arrays.asList(22, 44, 11, 33);      System.out.println(lstInt);  // [22, 44, 11, 33]   }}

3.6 ArrayList, Vector, LinkedList 和 Stack的比较


4. 排序与查找
  • 使用Collections.sort() 和 Arrays.sort()可进行排序
  • 有些集合,例如SortedSet (TreeSet) 和 SortMap (TreeMap)是有序的
有两种方法进行排序:
  • 是对象实现java.lang.Comparable,重写compareTo()方法去指定两个对象的排序方法。
  • 创建一个指定的java.util.Comparator对象,实现compare()方法去指定两个对象的比较。
4.1  java.lang.Comparable<T>接口
    java.lang.Comparable<T>可以指定两个对象如何进行比较,它定义了一个抽象方法。
int compareTo(T o)  // Returns a negative integer, zero, or a positive integer                     // as this object is less than, equal to, or greater than the given object

    一般推荐compareTo()方法与equals() 和 hashCode()是一致的,即:
  • 如果compareTo()返回0,那么equals()应该返回true。
  • 如果equals()返回true,那么hashCode()应该返回的是相同的int值。
   所有基本数据类型的包装类(例如:ByteShortIntegerLongFloatDoubleCharacter and Boolean)都实现了Comparable接口的compareTo() 方法。

例子:
        工具类 java.util.Arrays 和 java.util.Collections对应不同的算法提供了很多的静态方法,例如排序和查找。
在下面这个例子中,使用Arrays.sort() 和 Collections.sort() 方法去对一个String数组和一个Integer的List进行排序,使用的就是它们默认的Comparable实现。
import java.util.Arrays;import java.util.List;import java.util.ArrayList;import java.util.Collections; public class TestComparable {   public static void main(String[] args) {      // Sort and search an "array" of Strings      String[] array = {"Hello", "hello", "Hi", "HI"};       // Use the Comparable defined in the String class      Arrays.sort(array);      System.out.println(Arrays.toString(array));  // [HI, Hello, Hi, hello]       // Try binary search - the array must be sorted      System.out.println(Arrays.binarySearch(array, "Hello")); // 1      System.out.println(Arrays.binarySearch(array, "HELLO")); // -1 (insertion at index 0)       // Sort and search a "List" of Integers      List<Integer> lst = new ArrayList<Integer>();      lst.add(22);  // auto-box      lst.add(11);      lst.add(44);      lst.add(33);      Collections.sort(lst);    // Use the Comparable of Integer class      System.out.println(lst);  // [11, 22, 33, 44]      System.out.println(Collections.binarySearch(lst, 22)); // 1      System.out.println(Collections.binarySearch(lst, 35)); // -4 (insertion at index 3)   }}

4.2  java.util.Comparator<T> 接口
    在Comparable之外,我们可以传递一个Comparator对象到排序方法中(Collections.sort() 和 Arrays.sort())来实现大小比较,如果Comparator可用,那么Comparator将会重写Comparable。
int compare(T o1, T o2)    // Returns a negative integer, zero, or a positive integer as the                            // first argument is less than, equal to, or greater than the second.

    需要注意的是,你需要创建Comparator<T>实例,并且实现compare() 方法去进行对象的比较,在Comparable中,只需要调用对象的compareTo()方法,它只需要传递一个参数,表示当前对象和另一个对象比较,在Comparator<T>需要传递两个参数,表示两个对象的比较。

例子
import java.util.Arrays;import java.util.List;import java.util.ArrayList;import java.util.Collections;import java.util.Comparator; public class TestComparator {    // Define a Comparator<String> to order strings in case-insensitive manner   public static class StringComparator implements Comparator<String> {      @Override      public int compare(String s1, String s2) {         return s1.compareToIgnoreCase(s2);      }   }    // Define a Comparator<Integer> to order Integers based on the least significant digit   public static class IntegerComparator implements Comparator<Integer> {      @Override      public int compare(Integer s1, Integer s2) {         return s1%10 - s2%10;      }   }    public static void main(String[] args) {      // Use a customized Comparator for Strings      Comparator<String> compStr = new StringComparator();       // Sort and search an "array" of Strings      String[] array = {"Hello", "Hi", "HI", "hello"};      Arrays.sort(array, compStr);      System.out.println(Arrays.toString(array));  // [Hello, hello, Hi, HI]      System.out.println(Arrays.binarySearch(array, "Hello", compStr)); // 1      System.out.println(Arrays.binarySearch(array, "HELLO", compStr)); // 1 (case-insensitive)       // Use a customized Comparator for Integers      Comparator<Integer> compInt = new IntegerComparator();       // Sort and search a "List" of Integers      List<Integer> lst = new ArrayList<Integer>();      lst.add(42);  // auto-box      lst.add(21);      lst.add(34);      lst.add(13);      Collections.sort(lst, compInt);      System.out.println(lst);  // [21, 42, 13, 34]      System.out.println(Collections.binarySearch(lst, 22, compInt)); // 1      System.out.println(Collections.binarySearch(lst, 35, compInt)); // -5 (insertion at index 4)   }}

建议接着看Java编程手册-Collection框架(下)

参考文章:Java Programming Tutorial The Collection Framework

0 0
原创粉丝点击