集合類的要點總結

集合類的要點總結

1.     Collections.addAll  VS  Collection.addAll

Collection.addAll只能添加一個Collection類型的對象,而Collections.addAll支持可變參數列表。

public static void main(String[] args) {

       List<String> list1 = new ArrayList<String>();

       list1.add("a");

       list1.add("b");

       list1.add("c");

 

       List<String> list2 = new ArrayList<String>();

       list2.addAll(list1);//list2 [a,b,c]

       Collections.addAll(list2, "e","f");

       Collections.addAll(list2, list1.toArray(new String[]{}));//list2[a,b,c,e,f,a,b,c]

       for(int i=0; i<list2.size(); i++){

           System.out.println(list2.get(i));

       }

}

 

2.     Arrays.asList

這個方法接收一個可變參數,然後返回一個List類型的變量,但請注意,由於返回的List的內部實現包含的是

Private final E[] a;這樣的東西,所以返回的List對象不可以addremove,否則就會拋出java.lang.UnsupportedOperationException這個異常。

 

public static void main(String[] args) {

       List<String> strList = Arrays.asList("a","b","c");

       strList.add("d");//拋出java.lang.UnsupportedOperationException

       strList.remove(0);//拋出java.lang.UnsupportedOperationException

       System.out.println(strList);

}

 

3.     判斷一個集合類是否包含另一個集合類

利用Collection的非靜態方法containsAll(Collection col)進行判定,注意這裏採用的實現方法是遍歷col,調用contains方法一個一個進行判定,而contains方法則利用了equals方法進行判定。

class User{

   

    int age;

    String name;

   

    public User(int age , String name){

       this.age = age;

       this.name = name;

    }

 

    public boolean equals(Object object){

       User user = (User)object;

       return ( this.age==user.age && this.name.equals(user.name) );

    }

   

}

public final class ContainsAllTest {

 

    public static void main(String[] args) {

       List<User> list1 = new ArrayList<User>();

       list1.add(new User(1,"a"));

       list1.add(new User(2,"b"));

       list1.add(new User(3,"c"));

       List<User> list2 = new ArrayList<User>();

       list2.add(new User(1,"a"));

       System.out.println(list1.containsAll(list2));//true

    }

}

 

4.     Comparable VS Comparator(兩大比較器)

若想讓兩個對象具有可比性,有兩種方式,一種是讓該類直接實現Comparable接口,然後實現其compareTo方法,另一種方法是提供一個Comparator(比較器),比如在Collections.sort中可以自己提供一個比較器,從而可以適用各種各樣的比較。採用Comparable接口的方式只能實現一種比較方法,而採用Comparator則可以實現多種比較(每次比較提供不同的比較器),這其實便是設計模式中的策略模式。

一個使用Comparable的例子

public final class CompareTest {

 

    private static class User implements Comparable{

       String name;

       int age;

       private User(String name , int age){

           this.name  = name;

           this.age = age;

       }

       //先比較名字,大者則大,若名字相等再比較年齡

       public int compareTo(Object obj){

           User user = (User)obj;

           int result = this.name.compareTo(user.name);

           if(result != 0){

              return result;

           }

           return this.age>user.age?1:(this.age<user.age?-1:0);

       }

       public String toString(){

           return name + ":" + age ;

       }

    }

   

    public static void main(String[] args) {

       List<User> users = new ArrayList<User>();

       users.add(new User("zhangsan",20));

       users.add(new User("lisi",18));

       users.add(new User("wangwu",22));

       Collections.sort(users);

       for(User user : users){

           System.out.println(user);

       }

    }

}

//輸出結果爲
//lisi:18

//wangwu:22

//zhangsan:20

 

把該例子換成使用Comparator

public final class CompareTest {

 

    private static class User{

       String name;

       int age;

       private User(String name , int age){

           this.name  = name;

           this.age = age;

       }

       public String toString(){

           return name + ":" + age ;

       }

    }

   

    private static class ComparatorImpl implements Comparator{

 

       @Override

       public int compare(Object o1, Object o2) {

           User user1 = (User)o1;

           User user2 = (User)o2;

           int result = user1.name.compareTo(user2.name);

           if(result != 0){

              return result;

           }

           return user1.age>user2.age?1:(user1.age<user2.age?-1:0);

       }

      

    }

   

    public static void main(String[] args) {

       List<User> users = new ArrayList<User>();

       users.add(new User("zhangsan",20));

       users.add(new User("lisi",18));

       users.add(new User("wangwu",22));

       Collections.sort(users , new ComparatorImpl());

       for(User user : users){

           System.out.println(user);

       }

    }

}

//輸出結果爲

//lisi:18

//wangwu:22

//zhangsan:20

 

5.     求兩個Collection的交集

利用CollectionretainAll方法

public static void main(String[] args) {

       List<String> list1 = new ArrayList<String>();

       list1.add("a");

       list1.add("b");

       List<String> list2 = new ArrayList<String>();

       list2.add("b");

       list2.add("c");

       list1.retainAll(list2);

       System.out.println(list1);

}

//輸出結果爲

//[b]

 

6.     Iterator的三個基本方法

Iterator有三個方法,hasNext,next,remove,其中,remove刪除前一個next返回的那個元素。

    public static void main(String[] args) {

       List<String> strs = new ArrayList<String>();

       strs.add("a");

       strs.add("b");

       strs.add("c");

       Iterator<String> it = strs.iterator();

       while(it.hasNext()){

           System.out.println(it.next());

           it.remove();//刪除上面打出的元素

       }

       System.out.println("size = " + strs.size());

}

//輸出結果爲:

a

b

cvs

size = 0

 

7.     專門服務於ListListIterator

Iterator只有三個基本的方法,支持向前的迭代訪問,而專門針對於List,可以返回一個ListIterator的迭代器,它支持前後雙向的迭代,功能較強大。基本方法有

hasNextnexthasPreviouspreviousnextIndexpreviousIndexremovesetadd.

8.     Stack

Java.util包中有一個叫Stack的類,它直接繼承自Vector,我們知道,Vector 是同步的,所以此種Stack自然也是同步的。由於Vector中有許多不適用於Stack的方法,所以一般不使用此Stack。當要用到Stack的時候,一般情況下我們可以利用LinkedList方便的實現自己的Stack.

如下是一個簡單的自定義Stack的實現

public final class StaclTest {

 

    private static class Stack<T>{

       LinkedList<T> list = new LinkedList<T>();

       public boolean empty(){

           return list.isEmpty();

       }

       public T peek(){

           return list.getFirst();

       }

       public T pop(){

           return list.removeFirst();

       }

       public void push(T target){

           list.addFirst(target);

       }

       public int size(){

           return list.size();

       }

    }

   

    public static void main(String[] args) {

       Stack<String> stack = new Stack<String>();

       stack.push("a");

       stack.push("b");

       stack.push("c");

       printStack(stack);

       System.out.println("size = " + stack.size());

    }

   

    public static <T> void printStack(Stack<T> stack){

       int size = stack.size();

       for(int i=0; i<size; i++){

           System.out.println(stack.pop());

       }

    }

}

//輸出結果如下

c

b

a

size = 0

 

9.     認識map中的幾個主要方法

Map是非常重要的一種數據結構,有幾個比較重要的方法,

containsKey,containsValue,keySet,values,注意keySet方法。此方法返回一個Set類型的集合,但是這個Set裏邊裝的是Map.Entry這種類型的引用,何爲Map.Entry呢?其實,一個Map.Entry裏邊有一個keyvalue,所以一個Map.Entry就是對一對鍵值對的包裝,所以Map.EntrygetKeygetValue方法也就非常自然了。看一個簡單的例子

public static void main(String[] args) {

       Map<String,String> map = new HashMap<String,String>();

       Set<Map.Entry<String, String>> keySets = map.entrySet();

       map.put("1", "a");

       map.put("2", "a");

       System.out.println(keySets);

       Collection<String> values = map.values();

       System.out.println(values);

}

// 輸出結果爲

[2=a, 1=a]

[a, a]

 

10.  瞭解PriorityQueue

我想從它的名字就可以猜出它是一個有優先級作爲指導的隊列了,就像我們系統中有很多個進程一樣,每個進程都有不同的優先級,這是在j2se1.5中才新引入的。那麼如何設置其優先級呢?其實問題歸結到底還是迴歸到了Comparator(比較器)。

PriorityQueue有如下構造方法

PriorityQueue(int initialCapacity, Comparator<? super E> comparator)

第一個參數爲初始化容量大小,第二個爲一個比較器,這樣,你完全可以提供自己的比較器的實現類來指導PriorityQueue如何對元素按優先級進行訪問。注意,隊列只能在一端進行訪問,在另一端進行插入。PriorityQueue能夠保證每次獲取的數據都是按你所願的。但是如果你一下子打印出整個隊列的話,那麼它並不會整個都是排好序的,如下

public final class PriorityQueueTest {

 

    private static class ComparatorImpl implements Comparator{

       public int compare(Object obj1 , Object obj2){

           int result = ((Integer)obj1).compareTo((Integer)obj2);

           return result>0?-1:(result<0?1:0);

       }

    }

    public static void main(String[] args) {

       Queue<Integer> priorityQueue = new PriorityQueue<Integer>(10 , new ComparatorImpl());

       priorityQueue.add(10);

       priorityQueue.add(20);

       priorityQueue.add(8);

       priorityQueue.add(11);

       while(!priorityQueue.isEmpty()){

           System.out.println(priorityQueue);

           System.out.println("poll():" + priorityQueue.poll());

       }

    }

}

//運行結果如下

[20, 11, 8, 10]

poll():20

[11, 10, 8]

poll():11

[10, 8]

poll():10

[8]

poll():8

可以看出,直接打出PriorityQueue中的所有元素時並不是都排好序了,但是第一個元素絕對是正確的排序的。這跟它的具體實現有關,具體可以查看源代碼。(底層採用樹型結構存儲)

 

11.  Iterable接口的妙用

Jdk1.5中新增了加強的for語句,也就是foreach statement,它跟Iterable有何關係呢?其實,當一個類實現了Iterable接口後,便可用於foreach statement。看如下例子

public final class IterableTest {

    protected User[] users = new User[4];

   

    public User[] getUsers(){

       return this.users;

    }

    private static class User{

       private String name;

       public User(String name){

           this.name = name;

       }

       public String getName(){

           return this.name;

       }

    }

    private class MyCollection<T> implements Iterable<T>{

       private int index = 0;

       @Override

       public Iterator<T> iterator() {

           return new Iterator<T>(){

              

              @Override

              public boolean hasNext() {

                  return index < users.length;

              }

 

              @Override

              public T next() {

                  if(hasNext()){

                     return (T)users[index++];

                  }else{

                     return null;

                  }

              }

 

              @Override

              public void remove() {

                  throw new UnsupportedOperationException();

              }

             

           };

       }

    }

   

    public static void main(String[] args) {

       IterableTest myIterable = new IterableTest();

       User[] users = myIterable.getUsers();

       users[0] = new User("a");

       users[1] = new User("b");

       users[2] = new User("c");

       users[3] = new User("d");

       MyCollection<User> myColl = myIterable.new MyCollection<User>();

       for(User user : myColl){

           System.out.println(user.getName());

       }

    }

}

//輸出結果如下

a

b

c

d

注意如下代碼

MyCollection<User> myColl = myIterable.new MyCollection<User>();

這是非靜態內部類的創建方式。

當執行時,jvm會自動去調用myColl 中的iterator方法,然後利用返回的Iterator進行迭代。

發佈了40 篇原創文章 · 獲贊 174 · 訪問量 22萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章