集合概述:
集合可以看作是一個容器,對於集合中的對象很容易將其存放到集合中,也很容易將其從集合中取出來,還可以將其按照一定的順序進行擺放。Java中提供了不同的集合類,這些類具有不同的存儲對象的方式,並提供了相應的方法以方便用戶對集合進行遍歷、添加、刪除以及查找指定的對象。 提到容器不難想到數組,
集合類與數組的不同之處是:1.數組的長度是固定的,集合的長度是可變的;
2.數組用來存放基本類型的數據,集合用來存放對象的引用;
3.數組的元素類型一致,集合元素類型可以不一致;
常用的集合有List集合、Set集合、Map集合,其中List與Set實現了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來完成。
如果元素hashCode值相同,纔會判斷equals是否爲true。
如果元素的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(有序,可重複)
Set(無序,唯一)ArrayList: 底層數據結構是數組,查詢快,增刪慢。線程不同步,效率高。
LinkedList:底層數據結構是鏈表,查詢慢,增刪快。線程不同步,效率高。
Vector: 底層數據結構是數組,查詢快,增刪慢。線程同步,效率低。
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接口
集合常見應用功能
(添加功能,判斷功能,刪除功能,獲取功能,長度功能)