集合篇

1、集合框架 java

基於繼承特徵創建起的體系結構,集合框架至關龐大,首先看圖解:

算法

一、集合類出現的緣由:
    面向對象的核心就是對象,Java將全部的事物都封裝成對象,咱們要操做這些對象,就要將這些對象存儲起來,而集合就是存儲多個對象的容器。
數組

二、集合類特色:
    集合只用於存儲對象。集合長度是可變的。集合能夠存儲不一樣類型的對象。
安全

三、集合使用步驟:
    1) 建立集合對象。
    2) 建立元素對象。
    3) 把元素對象添加到集合對象中。
    4) 遍歷集合對象(經過集合對象獲取迭代器對象,經過迭代器對象的 hasNext()方法進行判斷,經過迭代器對象的 next()進行獲取)。
數據結構

四、數組與集合類同是容器,有何區別?
    1) 對象都使用集合存儲;數據都使用數組存儲。
    2) 數組雖然也能夠存儲對象,但長度是固定的;集合長度是可變長度的。
    3) 數組中存儲的是同一類對象,還能夠存儲基本數據類型;集合只能存儲對象。
    4) 數組存儲數據類型是固定的,而集合存儲的數據類型不固定。
多線程

2、Collection接口
    Collection 是層次結構中的根接口(頂層接口)。有兩個經常使用的接口 List 和 Set。在 List接口中有經常使用類 ArrayList、LinkedList 和 Vector;在 Set 接口中有類 HashSet、TreeSet。
一、Collection子類:
    List:元素有序,能夠重複。(由於有索引)
    Set:元素無序,不能夠重複。

二、Collection中常見的操做:
添加:
    boolean add(E e);    //添加指定元素;接收的是一個 Object 類型對象。
    boolean addAll(Collection<? extends E> c);    //添加集合,一次添加一堆元素。

刪除:
    void clear( );    //清空容器。移除 Collection 中的全部元素(可操做)
    boolean remove(Object o);    //移除一個指定元素
    boolean removeAll(Collection<? > c);      //移除一堆元素。只要有元素被刪除,就返回 true。

獲取:
   
   int size();  //獲取集合長度,若爲 0,則爲空,沒有元素。
判斷:
    boolean isEmpty();  //若不包含元素,返回 ture。

   boolean contains();  //包含指定元素,返回 ture。判斷是否含有某個元素。
    boolean containsAll(Collection c);   //判斷是否含有指定集合中的全部元素,只有全部數據都包含才返回 true

其餘:
    int hashCode( );    //返回此 collection 的哈希碼值
    Iterator <E>   iterator( );  //返回此元素上進行的迭代器,用於遍歷集合中的元素
    boolean retainAll( );    //取交集。只在調用者中保留共同的交集元素。
併發

三、迭代器:
1)概念:
   
其實就是集合取出元素的方式,將取出方式定義在集合內部,這樣取出方式就能夠直接訪問集合內部的元素。那麼取出方式就定義爲了內部類,而根據每一個數據結構的不一樣,去除取出方式也不一樣,但都有共性內容:判斷和取出,那麼久抽取出共性內容,將其封裝成對象Iterator。 集合均可以使用iterator()方法獲取取出對象Iterator。
2)迭代器的常見操做:

    hasNext();   //有下一個元素,返回真
    next();      //取出下一個元素
    remove();    //
移除
Note:在迭代時循環中next調用一次,就要hasNext判斷一次。
如下代碼演示迭代器的使用: app

public class CollectionDemo {

	public static void main(String[] args) {

		method_3();
	}
        public static void method_3() {
        // 建立一個集合容器,使用Collection接口的子類---ArrayList
        ArrayList al1 = new ArrayList();
        // 添加元素
        al1.add("demo1");
        al1.add("demo2");
        al1.add("demo5");
        al1.add("demo6");

        //獲取迭代器,第一種方法
        Iterator it1 = al1.iterator();
        while (it1.hasNext()) {
            System.out.println("while::"+it1.next());
        }
        //for循環,迭代器對象隨着循環結束而消失,內存開銷小,第二種方法
        for (Iterator it = al1.iterator(); it.hasNext();) {
            System.out.println("for::"+it.next());
        }

    }
}

結果如圖所示:

框架

迭代注意事項:
    1) 迭代器在Collcection接口中是通用的,它替代了Vector類中的Enumeration(枚舉)。
    2) 迭代器的next方法是自動向下取元素,要避免出現NoSuchElementException。
    3) 迭代器的next方法返回值類型是Object,因此要記得類型轉換。
ide

3、List
一、List
元素是有序的,元素能夠重複。由於該集合體繫有索引。
二、List 接口中的特有方法:
   add(int index,Object obj);      //在指定位置加入元素
   remove(int index);        //移除指定位置的元素
   set(int index,Object obj) ;      //修改指定位置的元素
   get(int index) ;      //獲取指定位置的元素
   indexOf(Object obj) ;      //獲取指定元素的位置
   subList(int start,int end) ;      //從一個大的 List 中截取一個小的 List
三、List 特有迭代器:
   ListIterator<E>   listIterator( );   //返回列表迭代器。
   ListIterator 是 Itertorde 子接口。 在迭代時,不能夠經過集合對象的方法操做集合中的元素,容易發生安全隱患;報錯:併發修改異常 ConcurrentModificationException。在迭代器時,只能用迭代器的方法操做元素,但是 Iterator 方法是有限的,只能對元素進行判斷、取出、刪除的操做,若是想要其餘的操做如添加,修改等,就須要使用其子接口,ListIterator。該接口只能經過 List 集合的 listIterator 方法獲取。
示例以下:

import java.util.ArrayList;
import java.util.ListIterator;

/* 
 * List集合特有的迭代器ListIterator是Iterator的子接口
 * 在迭代時,不能夠經過集合對象的方法來操做集合中的元素,由於會發生併發修改異常
 */
public class CollectionSub {
	public static void main(String[] args) {
	
		ArrayList al = new ArrayList();
		al.add("java01");
		al.add("java02");
		al.add("java03");
		al.add("java04");

		ListIterator li = al.listIterator();
		while (li.hasNext()) {
			Object obj = li.next();
			if (obj.equals("java02")) {
				li.set("java009");
			}
		}
		System.out.println(al);
		System.out.println("hasNext?" + li.hasNext());
		System.out.println("hasPrevious?" + li.hasPrevious());
	
	}
}

四、常見子類對象:
     ArrayList:底層的數據結構是數組結構,查詢快,增刪慢,線程不一樣步(長度初始值爲10,增量50%)
     LinkedList:底層是鏈表結構,增刪快,查詢慢
     Vector:底層是數組數據結構,線程同步,被ArrayList所取代,(長度初始值爲10,增量100%)
1)ArrayList
特有方法: (凡是能夠操做角標的方法都是該體系特有的方法)
添加:
    void add(int index , E element);    //在指定位置插入指定元素。
    boolean addAll(int index ,Collection<? extends E>  c); //將全部元素插入到列表中指定位置。
刪除:
    remove(int index);    //移除指定位置上的元素
修改:
    set(int index, E element);  //修改指定索引值上的元素
查詢:
    get(int index);      //  獲取位置索引
    int indexOf (Object o);    //判斷位置索引。若是不含該元素,則返回-1.
    subList(int fromIndex ,int toIndex);  //截取。含頭不含尾。
    boolean hasPrevious( );    //若是以逆向遍歷列表,列表迭代器有多個元素,則返回 true
2)Vector
特有方法:
    void   addElement();    //添加組件
    elementAt(int index);  //至關於 get 方法
    firstElement();    //獲取第一個組件
    insertElement(E obj , int index);  //插入
    last    Element();  //最後一個組件
    removeAllElements();  //移除
    public Enumeration elements();  //返回此向量的組件枚舉
    枚舉就是 Vector 特有的取出方式。枚舉和迭代是同樣的,但枚舉的名稱和方法的名稱都過長,因此就被迭代器取代了。
枚舉 Enumeration 的方法摘要:
    boolean hasMoreElements():  測試此枚舉是否包含更多的元素。
    E  nextElement():  若是此枚舉對象至少還有一個可提供的元素,則返回此枚舉的下一個元素。
Enumeration 是一個接口,此接口的功能與 Iterator 接口的功能是重複的。 此外, Iterator接口添加了一個移除操做,並使用較短的方法名。新的實現應該優先考慮 Iterator 接口,而不是 Enumeration 接口。
示例以下:

/*
 * Vector特有的去除方式--枚舉Enumeration
 * 枚舉和迭代都是同樣的
 */
import java.util.Enumeration;
import java.util.Vector;

public class VectorDemo {

	public static void main(String[] args) {
		Vector v = new Vector<>();

		v.add("java01");
		v.add("java02");
		v.add("java03");
		v.add("java04");
	
		Enumeration en = v.elements();
		while (en.hasMoreElements()) {
			System.out.println(en.nextElement());
		}
	}

}

3)LinkedList
特有方法:
    void addFirst( );   //在此列表的開頭插入指定的元素。
    void addLast( );
    getFirst();  //獲取元素,但不刪除元素
    getLast();
    removeFirst();    //獲取元素,但刪除元素,容量減小
    removeLast();    //當集合中沒有元素時,使用上面的方法會出現沒有這個元素異常NoSuchElementException
JDK1.6 版本出現下面代替方法:
    boolean offerFirst();  //在此列表的開頭插入指定的元素。
    boolean offerLast();    //在此列表末尾插入指定的元素。
    peekFirst(); //  獲取元素,但不刪除元素。若是集合中沒有元素,會返回 null。
    peekLast();
    pollFirst();  //  獲取元素,可是元素被刪除。若是集合中沒有元素,會返回 null。
    pollLast();
演示以下:

import java.util.LinkedList;

/*
 * LinkedList特有方法演示:
 */
public class LinkedListDemo {

	public static void main(String[] args) {
		LinkedList ll = new LinkedList();
		ll.addFirst("java01");
		ll.addLast("java01");
		ll.addLast("java02");
		ll.addLast("java03");
		ll.addLast("java04");
		System.out.println(ll.removeFirst());
		System.out.println(ll.getLast());
		System.out.println("長度:" + ll.size());
		while (!ll.isEmpty()) {
			System.out.println(ll.pollFirst());
		}
	}
}

4、Set
一、概述:
    Set:
元素是無序(存入和取出的順序不必定一致),元素不能夠重複。Set 繼承一個不包含重複元素的 Collection。Set 集合的功能和 Collection 是一致的。特色:惟1、無序、不重複。
    HashSet: 底層數據結構是哈希表。元素惟1、線程不安全,非同步。但效率高。容許使用 null。元素。不保證迭代順序,特別是它不保證該順序恆久不變。
    TreeSet: 底層數據結構是二叉樹。能夠對 Set 集合中的元素進行排序。
二、HashSet
HashSet:數據結構是哈希表,線程是非同步。
哈希表:根據哈希算法存儲的,存儲的就是對象的哈希值。它不保證 set 的迭代順序;特別是它不保證該順序恆久不變。此類容許使用 null 元素。
保證元素惟一性的原理:判斷元素的 hashCode 值是否相同。若相同,會繼續判斷元素的 equals 方法,是否爲 true。
示例以下:

import java.util.HashSet;
import java.util.Iterator;

/*
 * 	HashSet:
 * 		HashSet 中的 add 方法都作了什麼?
 *			添加集合元素,同時會調用 hashCode 方法,在內存中造成對象的哈希值。
 *			HashSet 中特有的 add 方法 (add 的返回值是 boolean 類型的) 自動調用 equals 方法:
 *			首先判斷元素的 hashCode 值是否相同。若不一樣,直接添加元素。若相同,會繼續判斷
 * 			元素的 equals 方法,元素相同返回 false,不添加元素;元素不一樣,返回 true,添加元素。
 * 		Tips:對於判斷元素是否存在以及刪除等操做,都是依賴於hashCode和equals方法
 */
class Person {
	private String name;
	private int age;

	Person(String name, int age) {
		this.name = name;
		this.age = age;
	}

	public void setName(String name) {
		this.name = name;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public int getAge() {
		return age;
	}

	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}

	@Override
	public int hashCode() {
		System.out.println(this.name + "...hashCode");
		return name.hashCode() + age * 39;
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof Person)) {
			return false;
		}
		Person p = (Person) obj;
		System.out.println(this.name + "...equals..." + this.age);
		return this.name.equals(p.getName()) && this.age == p.getAge();
	}

}

public class SetDefine {
	public static void main(String[] args) {
		HashSet hs = new HashSet<>();

		hs.add(new Person("zhangsan", 12));
		hs.add(new Person("li", 15));
		hs.add(new Person("li", 15));
		hs.add(new Person("wangwu", 23));
		hs.add(new Person("zhaoliu", 25));

		System.out.println(hs.contains(new Person("li", 15)));
		System.out.println(hs.remove(new Person("li", 15)));

		Iterator it = hs.iterator();
		while (it.hasNext()) {
			System.out.println(it.next());
		}
	}
}
結果如圖所示:

2)TreeSet
特色:
    1) 底層的數據結構爲二叉樹結構(紅黑樹結構)
    2) 可對Set集合中的元素進行排序,是由於:TreeSet類實現了Comparable接口,該接口強制讓增長到集合中的對象進行了比較,須要複寫compareTo方法,才能讓對象按指定需求(如人的年齡大小比較等)進行排序,並加入集合。
Note:排序時。當主要條件相同時,必定要判斷一下次要條件。
    Comparable:此接口強行對實現它的每一個類的對象進行總體天然排序,使元素具有比較性
    Comparator:強行對某個對象 collection 進行總體排序的比較函數,使集合具有比較性
TreeSet 排序的第一種方式:
    讓元素(集合)自身具有比較性。元素須要實現 Comparable 接口,覆蓋 compareTo 方法。這種方式也成爲元素的天然順序,或者叫作默認順序。基本數據類型或字符串對象均實現了 Comparable 接口,故同種類型基本數據間具有比較性,即天然順序。
TreeSet 排序的第二種方式:
    當元素自身不具有比較性時,或者具有的比較性不是所須要的。這時就須要讓集合自身具有比較性。定義比較器,將比較器對象做爲參數傳遞給TreeSet 構造函數。在集合初始化時,就有了比較方式。利用 TreeSet(Comparator Comparator); 構造方法構造一個新的空 TreeSet,它根據指定比較器進行排序。Comparator 是一個接口,接口中有兩個方法:
    int compare(T o1,T o2);  //比較用來排序的兩個參數。
    Boolean equals(Object o);   //指示某個其餘對象是否等於此「Comparetor」。
Note:當兩種排序都存在時,以比較器爲主。
示例以下:

import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;

/*
 * TeeSet:能夠對Set集合的元素排序
 * 		底層的數據結構是二叉樹保證元素的惟一性,依賴於compareTo方法
 * 排序方式:
 * 	一、讓元素自身具有比較性,元素須要實現Comparable接口覆蓋compareTo方法,完成天然排序的默認順序
 * 	二、當元素自身不具有比較性或者具有的比較性並不是所須要的,此時要讓集合自身具有比較性.定義比較器,將比較器對象做爲參數傳遞給TreeSet構造函數。
 * 	兩種方法排序是以比較器爲主		
 */

class Student implements Comparable { // 強制讓學生具有比較性
	private String name;
	private int age;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}

	@Override
	public int compareTo(Object o) {
		// TODO Auto-generated method stub
		if (!(o instanceof Student)) {
			throw new RuntimeException("不是學生對象!!!");
		}
		Student stu = (Student) o;
		return (this.age - stu.getAge()) == 0 ? this.name.compareTo(stu
				.getName()) : (this.age - stu.getAge());
	}

}

// 比較器
class myComparator implements Comparator {

	@Override
	public int compare(Object o1, Object o2) {
		// TODO Auto-generated method stub
		Student stu1 = (Student) o1;
		Student stu2 = (Student) o2;
		int nameOff = stu1.getName().compareTo(stu2.getName());
		return nameOff == 0 ? stu1.getAge() - stu2.getAge() : nameOff;
	}
}

public class TreeSetDemo {

	public static void main(String[] args) {

		TreeSet t = new TreeSet(new myComparator());
		t.add(new Student("zhangsan", 24));
		t.add(new Student("li", 23));
		t.add(new Student("wangwu", 23));
		t.add(new Student("zhaoliu", 23));
		t.add(new Student("zhaoliu", 25));

		Iterator it = t.iterator();
		while (it.hasNext()) {
			System.out.println(it.next());
		}

	}
}
結果以下所示:

5、Map<K,V>接口
一、Map 集合: 該集合存儲鍵值對,成對存入,保證鍵的惟一性。map 將鍵映射到值的對象。鍵值對之間用等號(=)鏈接。Map 和 Set 很像,Set 集合底層就是使用了 Map 集合。(K: 表明此映射所維護的鍵的類型      V: 表明映射值的類型)
二、Map集合子類:
       |--Hashtable    底層是哈希表結構,不能夠存入null鍵null值,線程是同步的
    |--HashMap    底層是哈希表結構,容許使用null鍵null值,線程不一樣步效率高
    |--TreeMap    底層是二叉樹結構,線程不一樣步,能夠用於給map集合中的鍵進行排序
三、Map集合經常使用方法:

添加:
   V put(K key, V value);    //將指定的值與此映射中的指定鍵關聯
Note:當 key 在集合中不存在時,添加元素;當 key 在集合存在的時,替換元素。即若添加時出現相同的鍵,那麼新添加的值會覆蓋原有的鍵對應值,而且 put 方法會返回所被覆蓋的值。

刪除:
   clear();    //移除全部鍵值對數據
   V remove(Object key); //  移除;根據指定鍵刪除鍵值對。
Note: 當不存在該鍵時,返回值爲 null;若存在該鍵, 則刪除該鍵,並返回該鍵所對應的值。

判斷:
   boolean containsValue(Object value);//判斷指定值是否在集合中存在,若此映射將一個或多個鍵映射到指定值返回true。
   boolean containsKey(); //判斷指定鍵是否在集合中存在。若此映射包含指定鍵的映射關係,則返回 true。
   boolean isEmpty();   //判斷集合是否爲空。若此映射未包含鍵、值映射關係,則返回 true。
獲取:
   Collection<V>   values();//獲取 map 集合中全部的值。獲取元素值,V 表明鍵值類型
   V  get(Object key); //根據鍵獲取值。返回指定鍵所在的值,若不存在該鍵,則返回 null。
Note:能夠經過 get()方法的返回值來判斷一個鍵是否存在。經過返回 null 來判斷。

   void putAll();    //從指定映射中將全部映射關係複製到此映射中
   int size();    //  獲取長度

演示以下:

import java.util.HashMap;
import java.util.Map;

/*
 * Map:存儲的是鍵值對,而且保證了鍵的惟一性
 * 	一、添加元素
 * 		put()
 * 		putAll()
 * 	二、刪除元素
 * 		clear()
 * 		remove()
 * 	三、判斷
 * 		boolean containsKey()
 * 		boolean containsValue()
 * 	四、獲取
 * 		get()
 * 		size()
 * 		values()
 * 
 * Map:
 * 	|--Hashtable	底層是哈希表結構,不能夠存入null鍵null值,線程是同步的
 * 	|--HashMap	底層是哈希表結構,容許使用null鍵null值,線程不一樣步效率高
 * 	|--TreeMap	底層是二叉樹結構,線程不一樣步,能夠用於給map集合中的鍵進行排序
 */
public class MapDemo1 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Map<String, String> map = new HashMap<String, String>();
		// 添加元素是若是出現相同的鍵,那麼後添加的值會覆蓋原有鍵對應的值,而且put方法會返回被覆蓋的值
		map.put("001", "zhangsan1");
		System.out.println(map.put("001", "lisi"));
		map.put("002", "zhangsan2");
		map.put("003", "zhangsan3");

		System.out.println("containsKey---" + map.containsKey("002"));
		// System.out.println("remove---" + map.remove("003"));

		// 能夠經過get方法的返回值來判斷一個鍵是否存在
		map.put("004", "not null");
		System.out.println("get---" + map.get(null));

		// 獲取map集合中全部的值,返回值Collections
		System.out.println("values---" + map.values());
		System.out.println(map);

	}
}
結果如圖所示:

四、Map集合元素的獲取:
由於Map中沒有迭代器,因此只能先用自有方法將元素轉移到有迭代器集合中再逐個迭代取出。此處有兩種方法:
1)Set<k>  keyset()    //返回全部鍵的集合。
原理:將 map 集合轉成 set 集合,再經過迭代器取出。返回此映射中包含的鍵的 Set 視圖;也就是將 map 中的全部鍵都存到 Set 集合中。由於:set 具有迭代器。因此能夠經過迭代方式取出全部的鍵,再根據 get()方法獲取每個鍵所對應的值。
步驟:
    a) 先獲取 map 集合的全部鍵的 Set 集合,經過 keySet()方法;
    b) 獲取迭代器,取得 map 全部鍵。而後經過 map 集合的 get()方法獲取元素對象的值。

2)set<Map.Entry<K,V>>  entrySet()  //鍵值對對象的結合。返回此映射中包含的映射關係的 Set 視圖。
原理:將 Map 集合中的映射關係存入到 Set 集合中。這個映射關係的數據類型是Map.entry,再經過 Map.Entry 類的方法再要取出關係裏面的鍵和值,Map.Entry<K,V>是一個靜態接口,能夠理解爲一種映射關係。

Note:Map.Entry<K,V>是一個靜態接口,能夠理解爲一種映射關係。Map.Entry 被封閉在 Map 接口中。其實 Entry 也是一個接口,表明一種映射關係。Entry 是 Map 接口中的一個內部接口。Map.Entry<K,V>中有如下方法:
    boolean equals();  //比較指定對象與此項的相等性
    getKey();    //返回與此項對應的鍵
    getValue();  //返回與此項對應的值
    int hashCode();  //返回此映像的哈希碼值
    setValue(value);  //用指定的值替換對應的值
3)步驟:
    a) 將 Map 集合中的映射關係取出,存入 Set 集合中。
    b) 經過 Map.Entry 類的方法再要取出關係裏面的鍵和值
兩種元素取出方式演示以下:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/*
 * Map鍵值對取出方式:
 * 	一、keySet:	
 * 		將map中全部的鍵存入Set集合中,由於Set集合有迭代器,利用迭代器取出key在利用map的get()方法獲取鍵對應的值
 * 	二、Set<Map.Entry<k,v>> entrySet:
 * 		將Map集合中的映射關係取出存入到Set集合中,再利用Set的迭代器獲取鍵值對
 * 
 */
public class MapDemo2 {

	public static void main(String[] args) {

		Map<String, String> map = new HashMap<String, String>();
		map.put("01", "zhangsan1");
		map.put("02", "zhangsan2");
		map.put("03", "zhangsan3");
		map.put("04", "zhangsan4");

		System.out.println("第一種方式取出");
		Set<String> mapSet = map.keySet();
		Iterator<String> itSet = mapSet.iterator();
		while (itSet.hasNext()) {
			String key = itSet.next();
			System.out.println(key + "--itSet--" + map.get(key));
		}

		System.out.println("第二種方式取出");
		Set<Map.Entry<String, String>> entrySet = map.entrySet();
		Iterator<Map.Entry<String, String>> itEntrySet = entrySet.iterator();
		while (itEntrySet.hasNext()) {
			Map.Entry<String, String> me = itEntrySet.next();
			System.out.println(me.getKey() + "--itEntrySet--" + me.getValue());
		}
	}

}
結果以下所示:

四、Map集合的拓展及應用:
1)Hashtable: 底層是哈希表的數據結構,不能夠存入 null 鍵 null 值。線程同步。
此類實現一個哈希表,該哈希表將鍵映射到相應的值。 任何非 null 對象均可以用做鍵或值。 在哈希表中存儲和獲取對象, 用做鍵的對象必須實現 hashCode()方法和 equals()方法(以能保證鍵的惟一性)。
2)HashMap: 基於哈希表的 map 接口實現,底層是哈希表的數據結構,並容許使用 null值、null 鍵,該集合線程不一樣步、無序。
保證元素惟一性的原理: 先判斷元素的 hashCode 值是否相同,再判斷兩元素的 equals方法是否爲true(往 HashSet 裏面存的自定義元素要複寫 hashCode 和 equals 方法,以保證元素的惟一性)

3)TreeMap: 底層是二叉樹數據結構。線程不一樣步,能夠用於給 map 集合中的鍵進行排序,其實 Set 底層就使用了 Map 集合。
應用實例以下:

import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;

/*
 * "asdadgaadgfgjnknckjnfvcxvergccxk"獲取字符串中的自摸出項的次數
 * 打印結果爲:a(2) b(3) ...
 * 
 * 一、將字符串轉換成字符數組
 * 二、定義一個Map集合
 * 三、遍歷字符數組。
 * 		將每個元素做爲鍵去查Map集合
 * 		若是返回值爲null,將該子母和1存入到Map中
 * 		若是返回不是null,則說明該字母出現過,將該字母對應的值自增1再存入Map中
 * 四、按照指定格式打印出來
 */
public class MapTest3 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String str = "asdadgaadgf--===gjnknckjnfvcxvergccxk";
		String result = charCount(str);
		System.out.println(result);
	}

	public static String charCount(String str) {
		//將字符串變成字符數組
		char[] chs = str.toCharArray();
		TreeMap<Character, Integer> tm = new TreeMap<Character, Integer>();
		int count = 0;//定義計數器
		for (int i = 0; i < chs.length; i++) {
			//剔除非字母字符
			if (!(chs[i] >= 'a' && chs[i] <= 'z' || chs[i] >= 'A'
					&& chs[i] <= 'Z')) {
				continue;
			}
			Integer value = tm.get(chs[i]);
			if (value != null) {
				count = value;
			}
			count++;
			tm.put(chs[i], count);
			count = 0;//每次循環後都將計數器置爲零
			/*
			 * if (value == null) { tm.put(chs[i], 1); } else { tm.put(chs[i],
			 * ++value); }
			 */
		}
		// System.out.println(tm);
		//定於StringBuilder存放結果
		StringBuilder sb = new StringBuilder();
		Set<Map.Entry<Character, Integer>> entrySet = tm.entrySet();
		Iterator<Map.Entry<Character, Integer>> it = entrySet.iterator();
		while (it.hasNext()) {
			Map.Entry<Character, Integer> me = it.next();
			Character ch = me.getKey();
			Integer in = me.getValue();
			sb.append(ch + "(" + in + ")");
		}

		return sb.toString();
	}
}

結果以下所示:

6、工具類
一、Collections: 集合框架的工具類。裏面定義的都是靜態方法。
Collections 和 Collection 有什麼區別?
Collection
: 是集合框架中的一個頂層接口,它裏面定義了單列集合的共性方法。它有兩個經常使用的子接口,List:對元素都有定義索引。有序的。能夠重複元素。Set:不能夠重複元素。無序。
Collections: 是集合框架中的一個工具類。該類中的方法都是靜態的。此類徹底由在 collection上進行操做或返回 collection  的靜態方法組成。提供的方法中有能夠對 list 集合進行排序,二分查找等方法。一般經常使用的集合都是線程不安全的。由於要提升效率。若是多線程操做這些集合時,能夠經過該工具類中的同步方法,將線程不安全的集合,轉換成安全的。
特色:方法都是靜態的,不須要建立對象。
    public static <T extends Comparable <? Super T>> void sort(List<T> list)    //排序。
    max();    //返回最大元素
    binarySearch();    //二分法查找,前提必須是有序集合。
    fill(); //能夠將 list 集合中全部元素替換成指定元素。 也能夠將 list 集合中部分元素替換成指定元素。
    replaceAll();    //替換,按元素替換
    reverse();  //反轉
    reverseOrder(); //反向排序,能夠強行逆轉比較器
    swap();    //置換
    shuffle();  //隨機排序

   集合有一個共同的缺點,那就是線程不安全,被多線程操做時,容易出現問題,雖然能夠本身加鎖,可是麻煩。Collections 提供特牛的方法,就是給它一個不一樣步的集合,它返回一個同步的安全的集合。
    synchronizdMap();   //返回指定列表支持的同步(線程安全的)映射。
    synchronizdList();  //返回指定列表支持的同步(線程安全的)列表。
    synchronizedSet();  //返回指定列表支持的同步(線程安全的)集合Set。

示例以下:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;

/*
 * 集合框架工具類:
 * Collections:全部的方法都是靜態的
 * 		一、排序方法:
 * 		static <T extends Comparator<? super T>> void sort(List<T> list)
 * 		staitc void sort(List<T> list,Comparator<? super T> com)
 */

class StringLngthComparator implements Comparator<String> {

	@Override
	public int compare(String o1, String o2) {
		// TODO Auto-generated method stub

		return o1.length() - o2.length() == 0 ? o1.compareTo(o2) : o1.length()
				- o2.length();
	}

}

public class CollectionsDemo {

	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("ijk");
		list.add("abcabc");
		list.add("fgh");
		list.add("cdef");
		list.add("lmn");

		Collections.sort(list, new StringLngthComparator());
		System.out.println(list);
		sortDemo(list);
		maxDemo(list);
		// 練習:將list集合中部分元素替換成指定元素
		fillDemo(list, "aa");
		replaceDemo(list, "fgh", "fff");
		System.out.println(list);
		reverseOrderDemo();
		shuffleDemo();
	}

	private static void shuffleDemo() {
		List<String> shu = new ArrayList<String>();
		shu.add("a");
		shu.add("ab");
		shu.add("fgh");
		shu.add("cdef");
		shu.add("zzzzzz");
		System.out.println(shu);
		Collections.shuffle(shu);
		System.out.println(shu);

	}

	public static void reverseOrderDemo() {
		TreeSet<String> set = new TreeSet<String>(Collections.reverseOrder());
		set.add("a");
		set.add("ab");
		set.add("fgh");
		set.add("cdef");
		set.add("zzzzzz");

		System.out.println(set);
	}

	public static void replaceDemo(List<String> list, String oldString,
			String newString) {
		Collections.replaceAll(list, oldString, newString);

	}

	public static void fillDemo(List<String> list, String str) {
		Collections.fill(list, str);
	}

	public static void maxDemo(List<String> list) {
		System.out.println("Max="
				+ Collections.max(list, new StringLngthComparator()));
	}

	public static void sortDemo(List<String> list) {
		System.out.println(list);
		Collections.sort(list, new StringLngthComparator());
		System.out.println(list);
	}

}

二、Arrays: 用於操做數組的工具類,裏面都是靜態方法。
    Lsit<T> asList(T... a)  //將數組變成 list 集合,可使用集合的思想和方法來操做數組中的元素。
    copyOfRange();    //將指定數組複製到新的數組。
    equals();         //比較數組元素是否徹底相同
    deepEquals();     //比較數組元素,而且比較元素內容是否相同。
    fill();    //替換數組中的元素,還能夠替換數組中的範圍。
    sort();    //排序
    toString();  //轉化成字符形式
Note:

    a)將數組變成集合,不可使用集合的增刪方法。不然會發生不支持操做異常(UnsupportedOperationException)。
    b)若是數組中的元素都是對象。那麼變成集合時,數組中的元素就直接轉成集合中的元素。
    c)若是數組中的元素都是基本數據類型,那麼會將該數組做爲集合中的元素存在。

示例以下:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/*
 * Arrays:
 * 
 * 數組變集合
 * asList(T... a)
 * 一、將數組變成集合目的是便於使用集合的方法操做,可是不能增刪不然會出現UnsupportionException
 * 二、若是數組中的元素都是對象,則直接轉成集合中的元素
 * 三、若是數組中的元素都是基本數據類型,那麼回將數組做爲集合中的元素
 * 
 * 集合變數組
 * toArray()
 */
public class ArraysDemo {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		asListDemo();
		toArrayDemo();
	}

	private static void toArrayDemo() {
		ArrayList<String> al = new ArrayList<String>();

		al.add("abc1");
		al.add("abc2");
		al.add("abc3");
		al.add("abc4");

		/*
		 * 一、指定類型的數組初始長度: -- 當指定數組的長度小於了集合的長度,那麼方法內部會從新建立一個新的數組長度和集合同樣
		 * 當指定的數組長度大於集合的長度,那麼就直接使用傳遞進來的數組 二、爲何將集合變數組:-- 爲了限定對集合元素的操做
		 */
		String[] arr = al.toArray(new String[5]);
		System.out.println(Arrays.toString(arr));
	}

	public static void asListDemo() {
		String[] arr = { "abc", "efg", "xyz" };
		int[] ar = { 1, 2, 3 };
		List<String> listStr = Arrays.asList(arr);
		System.out.println("Contains---" + listStr.contains("abc"));
		List<int[]> list = Arrays.asList(ar);
		System.out.println(list);
	}
}

   本篇幅所描述的僅表明我的見解,若有出入請見諒。

相關文章
相關標籤/搜索