1. 程式人生 > >Collection與Map

Collection與Map

onclick imp prim 就是 upper 請求 數據 cli inter

一、collection框架

技術分享圖片技術分享圖片

 (1)LIST

list是一種collection,作用是收集對象,並以索引的方式保留收集的對象的順序。其操作類之一就是Java.utl.ArrayList.ArrayList特性:隨機查找(list.get[i]),ArrayList內部就是用Object來保存收集的對象。此時就考慮到了數組的特性。根據數據結構內容我們只數組的好處就是隨機存儲速度快,排序等就可以考慮使用ArrayList

技術分享圖片
package Learn;

import java.util.ArrayList;
import java.util.Iterator;
import
java.util.List; import java.util.Scanner; public class ListDemo { public static void main(String[] args) { List name=new ArrayList();//收集信息的list collectNameTo(name);//收集函數 System.out.println("輸出訪客名單:"); printUpperCase(name);//輸出收集到的信息 } /** *@author
wbm *@param List *@deprecated通過控制臺輸入訪客的名稱,如果遇到quit則退出輸入訪客名稱的循環,每次循環都把收集到的信息通過List.add(信息對象)收集到list中去 */ static void collectNameTo(List names){ Scanner console=new Scanner(System.in);//控制臺輸入信息 while(true){ System.out.println("訪客名稱:"); String name
=console.nextLine(); if(name.equals("quit")){ break; } names.add(name);//把控制臺輸入的信息放入到list中去 } } /** *通過for循環把傳進來的List通過索引獲取list元素並轉換為string性,然後通過string的toUpperCase()轉為大寫 */ static void printUpperCase(List names){ for (int i = 0; i < names.size(); i++) { String name=(String) names.get(i);//通過索引獲得收集的信息 System.out.println(name.toUpperCase()); } } }
View Code

LinkedList特性:采用鏈接結構。鏈接結構簡單代碼如下。

技術分享圖片
package Learn;

public class LinkListDemo {
    private class Node{
        Object o;
        Node next;
        Node(Object o){
            this.o=o;
        }
    }
    private Node first;
    public void add(Object elem){
        Node node=new Node(elem);
        if(first==null){
            first=node;
        }
        else{
            append(node);
        }
    }
    private void append(Node node){
        Node last=first;
        while(first.next!=null){
            last=last.next;
        }
        last.next=node;
    }
    public int size(){
        int count=0;
        Node last=first;
        while(last.next!=null){
            last=last.next;
            count++;
        }
        return count;
    }
    public Object get(int index){
        checkSize(index);
        return findElemof(index);
    }
    private void checkSize(int index)throws IndexOutOfBoundsException{
        int size=size();
        if(index>=size){
            throw new IndexOutOfBoundsException( String.format("index:%d size:%d", index,size));
            
        }
    }
    private Object findElemof(int index){
        int count=0;
        Node last=first;
        while(count<index){
            last=last.next;
            count++;
        }
        return last.next;
    }

}
View Code

  (2)set

 也是收集對象,但是對象相同則不重復收集。知道不重復單詞個數有幾個代碼如下。

技術分享圖片
public static void mian(String[] args) {
        // TODO Auto-generated method stub
        Scanner scanner=new Scanner(System.in);
        System.out.println("請輸入英文");
        Set words=tokenSet(scanner.nextLine());//scanner.nextLine()String類型
        System.out.printf("不重復的字有%d個:%s%n",words.size(),words);
    }
    static Set tokenSet(String line){
        String[] tokens=line.split(" ");//根據空白切割字符串
        return new HashSet(Arrays.asList(tokens));//使用HashSet收集字符串
        
    }
View Code

使用set時得告訴怎樣的對象是相同,這時要用對象的hashCode()和equals()來判斷對象是夠相同。HashSet的操作哦該娘是,在內存中開設空間,每個空間都會有哈希編碼,這些空間稱為哈希桶,如果對象要加入哈希桶,則要調用對象的hashcode(),並嘗試放入對應的哈希桶中,如果哈希桶中沒有對象就放入,如果有對象就調用equals()進行比較。有無equals和hashcode的對比代碼如下

技術分享圖片
package Learn;

import java.util.HashSet;
import java.util.Set;

 class Student {
    private String name;
    private String number;
    Student(String name,String number){
        this.name=name;
        this.number=number;
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", number=" + number + "]";
    }

    
}

package Learn;

import java.util.HashSet;
import java.util.Set;

public class Students {
    
        public static void main(String[] args) {
            Set students=new HashSet();
            students.add(new Student("b","c"));
            students.add(new Student("b","c"));
            students.add(new Student("q","c"));
        System.out.println(students);

    }

}
結果:
[Student [name=q, number=c], Student [name=b, number=c], Student [name=b, number=c]]
package Learn;

import java.util.HashSet;
import java.util.Set;

 class Student {
    private String name;
    private String number;
    Student(String name,String number){
        this.name=name;
        this.number=number;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result + ((number == null) ? 0 : number.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        if (number == null) {
            if (other.number != null)
                return false;
        } else if (!number.equals(other.number))
            return false;
        return true;
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", number=" + number + "]";
    }
    
}
結果:
[Student [name=b, number=c], Student [name=q, number=c]]
View Code

java.util.TreeSet不僅有收集不重復對象的能力,還可以用紅黑樹的方式排序收集到的對象,條件就是收集到的對象必須是Comparable(否則會拋出ClassCastException),或者是在創建的是後指定comparator對象

 (3)quene

支持隊列操作,收集的對象加入至尾部,取得的對象時從前部,quene繼承自collection所以有add、remove、element等方法然而quene定義了自己的offer、poll、peak等方法主要區別在於,add、remove、element等方法操作失敗時會拋出異常,而offer、poll、peak會返回特定的值。對象需要使用隊列且長度受限是用通常使用poll、offer、peak方法。從架構圖可知linkedList不僅操作了queue的行為也操作了list的行為。所以可以將linkedlist當做隊列來使用。

簡單的代碼實例如下:

技術分享圖片
package Learn;

public interface Request {
     void execute();

}

package Learn;

import java.util.*;
/**
 * offer是在隊列前端加入對象成功會返回trues失敗會返回false。
 * poll是去除隊列的前端對象,若隊列為空則返回null。
 * peak是取得前端對象但是不取出若為空則返回null。
 * */
public class RequestQuene{
    public static void main(String[] args) {
        Queue requests=new LinkedList();
        offerRequestTo(requests);
        process(requests);
    }
    static void offerRequestTo(Queue requests){
        //請求加入隊列
        for(int i=1;i<6;i++){
            Request request=new Request(){
                @Override
                public void execute() {
                    // TODO Auto-generated method stub
                    System.out.printf("處理數據%f%n",Math.random());
                }
            };
            requests.offer(request);
            System.out.println(requests.offer(request));
        }
    }
    static void process(Queue requests){
        //處理隊列中的請求
        while(requests.peek()!=null){
            Request request=(Request)requests.poll();
            request.execute();
        }
    }
    
}
View Code

如果想要對隊列的前端和尾端進行操作,在前端加入對象和取出對象,在尾端加入對象和取出對象,queue的子接口Deque就定義了該行為。deque中定義addFirst()、removeFirst()、getFirst()、addLast()、

removeLast()、getLast()等方法,操作失敗時會拋出異常。而offerFirst()、pollFirst()、peekFirst()、offerLast()、pollLast()、peekLast()操作失敗會返回特定的值。java.util.ArrayDeque操作了Deque接口,操作使用容量有限的堆棧的簡單實例如下

技術分享圖片
package Learn;

import java.util.*;

public class Stack {
    private Deque elems=new ArrayDeque();
    private int capacity;
    Stack(int capacity){
        this.capacity=capacity;
    }
    public boolean push(Object elem){
        if(isFull()){
            return false;
        }
        else{
            return elems.offerLast(elem);
        }
    }
    private boolean isFull(){
        return elems.size()+1>capacity;
    }
    public Object pop(){
        return elems.pollLast();
    }
    public Object peek(){
        return elems.peekLast();
    }
    public int size(){
        return elems.size();
    }
    public static void main(String[] args) {
        Stack stack=new Stack(5);
        stack.push("justin");
        stack.push("wbm");
        stack.push("wcy");
        System.out.println(stack.pop());
        System.out.println(stack.pop());
        System.out.println(stack.pop());
    }

}
結果:
wcy
wbm
justin
堆棧是先進後出
View Code

queue的操作類之一java.util.PriorityQueue也是,收集至PriorityQueue的對象,會根據你指定的優先權來決定對象在隊列中的順序,優先的告知,要不是對象必須是comparable,或者是在創建PriorityQueue時指定comparator對象。

(3)Interable與Iterator

iterator方法JDK5之前是定義在collection中在JDK5之後定義在iterable;具體的一些好處和細節如下代碼。

技術分享圖片
    //收集LIst對象
    static void forEachList(List list){
        int size=list.size();
        for(int i=0;i<size;i++){
            System.out.println(list.get(i));
        }
    }
    //收集set對象
    static void forEachSet(Set set){
        for(Object o:set.toArray()){
            System.out.println(o);
        }
    }
    //收集queue對象
    static void forEachQueue(Queue queue){
        while(queue.peek()!=null){
            System.out.println(queue.poll());
        }
    }
    //含有這個方法的類是util,那麽你就可以指定使用util.<String> elemOf()的方式指定E的實際類型
    public static<E> E elemOf(E[] objs,int index){
        return objs[index];
    }
    //無論是Queue、List、Set都會有iterator方法JDK5之前是定義在collection中在JDK5之後定義在iterable
    static void forEachCollection(Collection collection){
        Iterator iterator=collection.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
    static void forEachIterable(Iterable iterable){
        Iterator iterator=iterable.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
View Code 技術分享圖片
package Learn;

import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;

public class forEach {
    public static void main(String[] args) {
        List names=Arrays.asList("ww","bb","mm");//靜態方法aslist接收不定長自變量將其指定為List
        forEach(names);//list是一種Iterable.
        forEach(new HashSet(names));//List是一種collection,hashSet是一種collection接收collection的構造函數所以list可以用來創建hashset
        forEach(new ArrayDeque(names));//同理
    }
    static void forEach(Iterable iterable){
        for (Object object : iterable) {
            System.out.println(object);
        }
        
    }

}
View Code

(4)comparable與comparator

1. comparable(comparaTo()) 

  在收集對象之後,對對象排序是常用的動作,我們不用親自操作排序算法,java.util.collections

技術分享圖片
List numbers=Arrays.asList(10,5,1,9,8,9,7);
        Collections.sort(numbers);
        System.out.println(numbers);
結果為:[1, 5, 7, 8, 9, 9, 10]
View Code

如果沒有說明list元素的比較會出現錯誤

技術分享圖片
package Learn;

import java.util.HashSet;
import java.util.Set;

 class Student {
    private String name;
    private String number;
    Student(String name,String number){
        this.name=name;
        this.number=number;
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", number=" + number + "]";
    }
}

package Learn;

import java.util.Arrays;
import java.util.Collections;

import java.util.List;


public class Students {
        public static void main(String[] args) {
            List students=Arrays.asList(new Student("b","c"),new Student("b","c"),new Student("q","c"));
            Collections.sort(students);
        System.out.println(students);

    }
}
出現:
java.lang.ClassCastException:
View Code

collections.sort()的操作對象必須操作java.lang.comparable接口,這個接口有compareTo()方法的返回值必須大於0,等於0或小於0的整數。

技術分享圖片
package Learn;

import java.util.HashSet;
import java.util.Set;

 public class Student implements Comparable<Student> {
    private String name;
    private String number;
    Student(String name,String number){
        this.name=name;
        this.number=number;
    }
    @Override
    public String toString() {
        return "Student [name=" + name + ", number=" + number + "]";
    }
    @Override
    public int compareTo(Student o) {
        // TODO Auto-generated method stub
        return Integer.parseInt(this.number)-Integer.parseInt(o.number);
    }
}

package Learn;

import java.util.Arrays;
import java.util.Collections;

import java.util.List;


public class Students {
        public static void main(String[] args) {
            List students=Arrays.asList(new Student("b","1"),new Student("b","3"),new Student("q","2"));
            Collections.sort(students);
        System.out.println(students);

    }
}

結果為
[Student [name=b, number=1], Student [name=q, number=2], Student [name=b, number=3]]
View Code

2.compatator(compare())

如果對象無法操作comparable的話呢?比如String本身有操作Comparable,所以可以按字母的排序如果我想要把字母排序的順序反過來呢?String是final的類型不能被繼承所以無法重新定義compareTo()方法。Collection有另一個重載版本,可以接受java.lang.Comparator接口的操作對象。流程:1.定義一個comparator:class StringComparator implements<String>{ public int compare(String s1,String s2){ return s1.compareTo(s2);}} 2.調用:Collections.sort(List,new StringComparator());

技術分享圖片
package Learn;

import java.util.Comparator;

public class StringComparator implements Comparator <String> {

    @Override
    public int compare(String o1, String o2) {
        // TODO Auto-generated method stub
        return -o1.compareTo(o2);
    }

}


package Learn;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;

public class sort {
    public static void main(String[] args) {
        List<String> words=Arrays.asList("B","A","C");
        Collections.sort(words,new StringComparator());
        System.out.println(words);
    }
}
結果
[C, B, A]
View Code

二、Map框架

三、簡單泛型的使用

  在使用Collection收集對象時,由於事先不知道對象的形態使用的是Object來收集,取回對象也是Object,所以執行期間失去了形態的信息。所以取回對象之後要記得對象的真正的類型,然後讓對象重新扮演

  自己的類型。

技術分享圖片
List names=Array.asList("ww","bb","mm");
String name=(String)name.get(0);
ArrayList<String> names= new ArrayList<String>();
names.add("justin");
names.add("wbm");
names.add(new Long(10));//編譯會出錯沒法通過。
String name1=names.get(0);
string nmae2=names.get(1);
View Code

 靜態方法上定義類型

//含有這個方法的類是util,那麽你就可以指定使用util.<String> elemOf()的方式指定E的實際類型
    public static<E> E elemOf(E[] objs,int index){
        return objs[index];
    }

Utilizes

  Collections:是針對集合類的一個幫助類,提供了操作集合的工具方法:一系列靜態方法實現對各種集合的搜索、排序、線程

        安全化等操作。

  Arrays:針對數組的一個幫助類,提供了操作arrays的工具方法:一系列靜態方法對各種數組的搜索、排序等操作

    

Collection與Map