java集合框架

集合概述:

          集合可以看作是一個容器,對於集合中的對象很容易將其存放到集合中,也很容易將其從集合中取出來,還可以將其按照一定的順序進行擺放。Java中提供了不同的集合類,這些類具有不同的存儲對象的方式,並提供了相應的方法以方便用戶對集合進行遍歷、添加、刪除以及查找指定的對象。 提到容器不難想到數組,

                                         集合類與數組的不同之處是:1.數組的長度是固定的,集合的長度是可變的;

                                                                                        2.數組用來存放基本類型的數據,集合用來存放對象的引用;

                                                                                        3.數組的元素類型一致,集合元素類型可以不一致;

   常用的集合有List集合、Set集合、Map集合,其中ListSet實現了Collection接口。各接口還提供了不同的實現類。上述集合類的關係如下圖所示:

  

Collection:定義了集合框架的共性功能。
(1)List(列表):元素是有序的,元素可以重複,因爲該集合體繫有索引。

                                  ArrayList:底層是數組數據結構,查詢速度很快,但是增刪稍慢,線程不同步,默認10個元素。(線程不同步)

                                  LinkedList:底層是鏈表數據結構,查詢很慢,增刪速度很快。(線程不同步)

(2)Set(集):元素是無序的(存入和取出順序不一定一致),元素不可以重複。

                                  HashSet:底層數據結構是哈希表。線程是不同步的。

                                                   採用散列函數對元素進行排序Asiic),是專門爲快速查詢而設計的。存入HashSet的對象必須定義hashCode方法。

                                  LinkedHashSet:有序。

                                                    內部使用散列以加快查詢速度,同時使用鏈表維護元素插入的次序,在使用迭代器遍歷Set時,

                                                    結果會按元素插入的次序顯示。 

                                TreeSet:底層的數據結構是二叉樹。線程是不同步的。

          注意:集合只能保存引用數據類型,也就是存儲的是對象的地址值,而不是對象本身。集合中的元素相當於引用類型變量。

package com.wyb.collection;

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

public class CollectionOfList {
	public static void main(String[] args) {
		List<StringAddress> list = new ArrayList<StringAddress>(Collections.nCopies(4, new StringAddress("Hello")));
		System.out.println(list);
		Collections.fill(list, new StringAddress("World"));
		System.out.println(list);
		List<String> list1 = Arrays.asList(new String[] {"spring","summer","autumn","winter"});
		Collections.sort(list1);
		System.out.println(Collections.max(list1));
		System.out.println(Collections.min(list1));
		System.out.println(Collections.binarySearch(list1, "spring"));
		System.out.println(Arrays.toString(list1.toArray()));
		Collections.shuffle(list1);   //重新隨即調整list中元素的位置1
		System.out.println(Arrays.toString(list1.toArray()));
	}

}
class StringAddress
{
	private String s;
	public StringAddress(String s)
	{
		this.s = s;
	}
	public String  toString()
	{
		return super.toString()+" "+s;
	}
}
Set :元素是無序的(存入和取出順序不一定一致),元素不可以重複。

HashSet是如何保證元素唯一性的呢?

是通過兩個方法,hashCode和equals來完成。

如果元素hashCode值相同,纔會判斷equals是否爲true

如果元素的hashCode不同,不會調用equals方法。

怎麼重寫hashCode()和equals()方法呢?

hashCode():把對象的所有成員變量值相加即可。

如果是基本數據類型,就加值。如果是引用類型,就加哈希值。
return name.hasCode()+ age * 27;
equals(obj):先判斷是否是同一類型的對象,再把傳遞進來的對象進行向下轉型。再判斷對象的內容是否相同。

if(!(obj instanceof Student)) ;

Student stu = (Student)obj; 

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

所有成員變量的值比較。基本類型用==,引用類型用equals()。

注意:對於判斷元素是否存在,以及刪除等操作,依賴的方法是元素的hashCode和equals方法。


package com.wyb.collection;

import java.util.Collection;
import java.util.HashSet;

public class HashSetTest {
	/**
	 * HashSet類按照哈希算法來存取容器中的對象,具備很好的存取和查找性能。
	 * @param args
	 */
	public static void main(String[] args) {
		Collection<Object> c = new HashSet<Object>();
		c.add(new Person("Jack",20));
		c.add(new Person("Jack",20));
		System.out.println(c.size());
		System.out.println(c);
		c.add(new Integer(25));
		c.add("Hello World");
		System.out.println(c);
		c.remove(new Integer(25));
		c.remove("Hello World");
		System.out.println(c.remove(new Person("jack",20)));
		
	}

}
class Person
{
	private String name;
	private int age;
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public boolean equals(Object obj)  //重寫equals方法
	{
		if(obj instanceof Person)  //實例化
		{
			Person p = (Person) obj;
			return (name.equals(p.name)) && (age==p.age);
		}
		return super.equals(obj);
	}
	public int hashCode() //重寫hashCode方法
	{
		int i;
		i=(name==null?0:name.hashCode());//判斷name是否爲空
		i=10*i+age;
		return i;
	}
}

TreeSet :底層的數據結構是二叉樹。線程是不同步的。


package com.wyb.collection;

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

public class ComputerComparator implements Comparator<Computer>{
	/**
	 * 實現Comparator接口,加入TreeSet容器中對向以brand降序排列,和place生序排列
	 */
	public static void main(String[] args) {
		Set<Computer> set = new TreeSet<Computer>(new ComputerComparator());
		set.add(new Computer("dell","shanghai"));
		set.add(new Computer("hp","shenzhen"));
		set.add(new Computer("hp","Guangzhou"));
		set.add(new Computer("lenovo","Beijing"));
		set.add(new Computer("dell","Beijing"));
		Iterator<Computer> it = set.iterator();
		while(it.hasNext())
		{
			Computer c = it.next();
			System.out.println(c);
		}
	}

	@Override
	public int compare(Computer c1, Computer c2) {
        if(c1.brand.compareTo(c2.brand)>0)   //brand降序
        	return -1;
        else if(c1.brand.compareTo(c2.brand)<0)
        	return 1;
        else
        	return c1.place.compareTo(c2.place);//place生序
		
	}

}
class Computer
{
	String brand;
	String place;
	public Computer(String brand, String place) {
		super();
		this.brand = brand;
		this.place = place;
	}
	@Override
	public String toString() {
		return "Computer [brand=" + brand + ", place=" + place + "]";
	}
	public boolean equals(Object obj)   //重寫equals方法
	{
		if(!(obj instanceof Computer))
			return false;
		Computer c = (Computer) obj;
		if(this.brand.equals(c.brand) && this.place==c.brand)
			return true;
		else
			return false;
	}
	public int hashCode()  //重寫hashCode方法
	{
		int result;
		result = (brand==null?0:brand.hashCode());
		return result;
	}
}
package com.wyb.collection;

import java.util.LinkedList;
//import java.util.Random;

public class LinkedListTest {
	/**
	 * LinkedList在內部是採用雙向循環鏈表實現對,
	 * 插入與刪除元素的速度較快,隨即訪問則較慢。
	 * LinkedList單獨具有addFirst()、addLast()、getFirst()、getLast()
	 * removeFirst()和removeLast()方法
	 * @param args
	 */
	public static void main(String[] args) {
//		Random r = new Random(49);
		LinkedList<String> list = new LinkedList<String>();
		list.add(new String("rat"));
		list.add(new String("monkey"));
		list.add(new String("pig"));
		list.add(new String("rabbit"));
		System.out.println("list:"+list);
		System.out.println("list.getFirst:"+list.getFirst());
		System.out.println("list.element:"+list.element());
		System.out.println("list.peek:"+list.peek());
		System.out.println("list.remove:"+list.remove());
		System.out.println(list.removeFirst());
		System.out.println("poll:"+list.poll());
		System.out.println("list:"+list);
		list.addFirst(new String("mouse"));
		System.out.println("after addFirst:"+list);
		list.offer(new String("dog"));
		System.out.println(list);
		list.add(new String("rabbit"));
		System.out.println(list);
		list.addLast(new String("goat"));
		System.out.println(list);
		System.out.println(list.removeLast());
		System.out.println(list);
	}

}

Map<K,V>集合:該集合存儲鍵值對。一對一往裏存,而且要保證鍵的唯一性。

|--HashMap:基於哈希表的Map接口的實現。此實現提供所有可選的映射操作,並允許使用null 值和null鍵。

(除了非同步和允許使用null 之外,HashMap 類與Hashtable 大致相同。)此類不保證映射的順序,特別是它不保證該順序恆久不變。  Hashtable替代,JDK1.2.效率高。

 |--TreeMap:基於紅黑樹(Red-Black tree)的 NavigableMap 實現。該映射根據其鍵的自然順序進行排序,或者根據創建映射時提供的 Comparator(比較器) 進行排序,具體取決於使用的構造方法。 
和Set很像。其實大家,Set底層就是使用了Map集合。線程不同步。可以用於給Map集合中的鍵進行排序。

(1)Map是一個鍵值對形式的集合。它的元素都是由鍵和值組成。

(2)Map和Collection的區別?

A:Map 是由鍵值對組成的集合,Map的鍵是唯一的,值可以重複。

B:Collection 是有單列數據組成的集合,它的子類List是可以重複的,Set是唯一的。

(3)HashMap和Hashtable的區別?

HashMap:線程不安全,效率高。允許null鍵和值。

Hashtable:線程安全,效率低。不允許null鍵和值。

Map集合的兩種取出方法

1. Set<k> keySet:將Map中所有的鍵存入到Set集合,因爲Set具備迭代器。

    所以可以迭代方式取出所有的鍵,再根據get方法獲取每個鍵對應的值

    Map集合取出原理:將Map集合轉化成Set集合,再通過迭代器取出。

2.Set<Map.Entry<k,v>> entrySet:將Map集合中的映射關係存入到Set集合中,而這個關係的數據類型就是:Map.Entry

package com.wyb.collection;

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

public class MapTest {
	/**
	 * 向容器中查詢某一學生信息,如果存在則將該學生信息打印出來
	 * 並對容器中的5個學生信息依總學分的生序打印出來
	 * 
	 * 思路:
	 * 由於TreeMap容器中的值對象是student,需要一一取出它們,計算總學分,
	 * 再以總學分作爲鍵對象放入到TreeMap容器中,值對象依然以student。
	 * TreeMap容器會自動以自然順序對鍵值對進行排序
	 * @param args
	 */
	public static void main(String[] args) {
		TreeMap<Integer,Student> tm = new TreeMap<Integer,Student>();
		int total = 0;
		int[] grade = new int[5];
		Student[] s = new Student[5];
		tm.put(100001, new Student(100001, "王軍", 85, 75, 95));
		tm.put(100002, new Student(100002, "小紅", 90, 70, 80));
		tm.put(100003, new Student(100003, "小明", 92, 80, 80));
		tm.put(100004, new Student(100004, "旺財", 80, 87, 76));
		tm.put(100005, new Student(100005, "小強", 80, 70, 60));
		int[] arr = new int[5];
		int i = 0;
		int j = Integer.parseInt(args[0]);
		System.out.println("學號  姓名   計算機成績  數學成績  英語成績  總分");
		if(tm.containsKey(j))
		{
			System.out.println("你要查找的學生信息是:");
			Student stu = tm.get(j);
			System.out.println(stu.id+"  ");
			System.out.println(stu.name+"  ");
			System.out.println(stu.computer_sore+"  ");
			System.out.println(stu.math_sore+"  ");
			System.out.println(stu.english_sore+"  ");
			total = stu.computer_sore+stu.math_sore+stu.english_sore;
			System.out.println(total);
		}
		System.out.println();
		TreeMap<Integer,Student> tp = new TreeMap<Integer,Student>();
		Iterator<Map.Entry<Integer, Student>> it = tm.entrySet().iterator();
		System.out.println("按總學分排序:");
		while(it.hasNext())
		{
			Map.Entry entry = it.next();
			arr[i] = (Integer) entry.getKey();
			s[i] = (Student) entry.getValue();
			System.out.print(s[i].id+"   ");
			System.out.print(s[i].name+"   ");
			System.out.print(s[i].computer_sore+"   ");
			System.out.print(s[i].math_sore+"   ");
			System.out.print(s[i].english_sore+"   ");
			total = s[i].computer_sore+s[i].english_sore+s[i].math_sore;
			System.out.println(total);
			System.out.println();
			grade[i]=total;
			tp.put(grade[i], s[i]);
			i++;
		}
		i=0;
		System.out.println("按總學分排序後:");
		Iterator<Map.Entry<Integer, Student>> iter = tp.entrySet().iterator();
		while(iter.hasNext())
		{
			Map.Entry entry1 = iter.next();
			arr[i] = (Integer) entry1.getKey();
			s[i] = (Student) entry1.getValue();
			System.out.print(s[i].id+"   ");
			System.out.print(s[i].name+"   ");
			System.out.print(s[i].computer_sore+"   ");
			System.out.print(s[i].math_sore+"   ");
			System.out.print(s[i].english_sore+"   ");
			total = s[i].computer_sore+s[i].english_sore+s[i].math_sore;
			System.out.println(total);
			System.out.println();
		}
	}

}
class Student
{
	int id;
	String name;
	int math_sore;
	int english_sore;
	int computer_sore;
	public Student(int id, String name, int math_sore, int english_sore,
			int computer_sore) {
		super();
		this.id = id;
		this.name = name;
		this.math_sore = math_sore;
		this.english_sore = english_sore;
		this.computer_sore = computer_sore;
	}
	
}

集合體系

Collection(單列)

List(有序,可重複)

ArrayList:  底層數據結構是數組,查詢快,增刪慢。線程不同步,效率高。  


LinkedList:底層數據結構是鏈表,查詢慢,增刪快。線程不同步,效率高。


Vector:      底層數據結構是數組,查詢快,增刪慢。線程同步,效率低。

Set(無序,唯一)

HashSet:底層數據結構是哈希表。線程不同步,效率高。 怎麼保證唯一性的呢?它依賴兩個方法:hashCode()和equals()順序:首先判斷hashCode()值是否相同。同:繼續走equals(),看返回值如果true:就不添加到集合。如果false:就添加到集合。不同:就添加到集合。

TreeSet:底層數據結構是二叉樹。 線程不同步,效率高。 怎麼保證唯一性的呢?是根據返回是否是0。

怎麼保證排序的呢?兩種方式 

一、自然排序(元素具備比較性) 實現Comparable接口 

二、比較器排序(集合具備比較性) 實現Comparator接口

Map(雙列 底層結構是針對鍵有效,跟值無關)

HashMap:底層數據結構是哈希表。線程不同步,效率高。

怎麼保證唯一性的呢?

它依賴兩個方法:hashCode()和equals()順序:首先判斷hashCode()值是否相同。同:繼續走equals(),看返回值如果true:就不添加到集合。如果false:就添加到集合。不同:就添加到集合。


Hashtable:底層數據結構是哈希表。線程安全,效率低。

怎麼保證唯一性的呢?

它依賴兩個方法:hashCode()和equals()順序:首先判斷hashCode()值是否相同。同:繼續走equals(),看返回值如果true:就不添加到集合。如果false:就添加到集合。不同:就添加到集合。


TreeMap:底層數據結構是二叉樹。線程不同步,效率高。

怎麼保證唯一性的呢?是根據返回是否是0。

怎麼保證排序的呢?兩種方式自然排序(元素具備比較性)實現Comparable接口比較器排序(集合具備比較性)實現Comparator接口

集合常見應用功能

(添加功能,判斷功能,刪除功能,獲取功能,長度功能)



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