類集 類集:主要功能就是Java數據結構的實現(java.util) 類集就是動態對象數組(鏈表也是動態數組) Collection 介面 Collection是整個類集之中單值保存的最大 父介面 。即:每一次僅可以向集合中保存一個對象 在Collection定義的常用操作方法 常用操作方法 向集合 ...
類集
- 類集:主要功能就是Java數據結構的實現(java.util)
- 類集就是動態對象數組(鏈表也是動態數組)
Collection 介面*
- Collection是整個類集之中單值保存的最大 父介面 。即:每一次僅可以向集合中保存一個對象
public interface Collection<E>
extends Iterable<E>
- 在Collection定義的常用操作方法
常用操作方法
- 向集合中保存數據
public boolean add(E e);
- 追加一個集合
public boolean addAll(Collection<? extends E>c);
- 清空集合(根元素為null)
public void clear();
- 判斷是否有指定的內容
public boolean contains(Object o);
- 判斷是否為空集合
public boolean isEmpty();
- 刪除對象
public boolean remove(Object o);
- 取得元素個數
public int size();
- 以對象數組保存集合
public Object [] toArray();
- 為Iterator介面實例化
public Iterator<E> iterator();
contains() 和 remove() 一定要依靠 equals() 的支持;
List子介面
- List子介面是Collection介面中最常用的子介面;
- List對Collection介面進行了功能的擴充;
常用操作
- 取得索引編號的內容
public E get(int index);
- 修改索引的內容
public E set(int index , E element);
- 為LisIterator介面實例化對象
public ListIterator<E> listIterator();
List屬於介面,如果想使用介面進行操作,就必須存在子類;使用 ArrayList 子類實現(和Vector子類)
ArrayList子類
public static void main(String [] args) throws IOException {
List<String> all = new ArrayList<String>();
System.out.println("size:" + all.size() + "Null:" + all.isEmpty());
all.add("Hello");
all.add("Hello");
all.add("World");
System.out.println("size:" + all.size() + "Null:" + all.isEmpty());
// Collection介面定義了size()方法取得集合長度
// List子介面增加了 get() 方法,可取取得所有的數據
for (int x = 0 ; x < all.size() ; x++) {
String str = all.get(x);
System.out.println(str);
}
}
}
通過對ArrayList()子類的使用分析在:List集合中所保存的數據是按照保存的順序存放的,而且允許重覆數據;List子介面有get()方法,可以獲得集合中指定序列的內容
- 為Collection介面實例化
public class TestDemo {
public static void main(String [] args) throws IOException {
Collection<String> all = new ArrayList<String>();
System.out.println("size:" + all.size() + "Null:" + all.isEmpty());
all.add("Hello");
all.add("Hello");
all.add("World");
System.out.println("size:" + all.size() + "Null:" + all.isEmpty());
Object[] obj = all.toArray();//變為對象數組讀取數據
for (int x = 0 ; x < obj.length ; x ++) {
System.out.println(obj[x].toString());
}
/*for (int x = 0 ; x < all.size() ; x++) {
String str = all.get(x);// 由於Collection類中沒有get()方法所以無法使用
System.out.println(str);
}*/
}
}
- List保存對象
class Book {
private String title ;
private double price ;
public Book(String title , double price) {
this.price = price;
this.title = title;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true ;
}
if (obj == null) {
return false;
}
if(!(obj instanceof Book)) {
return false ;
}
Book book = (Book) obj;
if (this.title.equals(book.title) && this.price == book.price){
return true;
}
return false;
}
@Override
public String toString() {
return this.title + "\t" + this.price + "\n";
}
}
public class TestDemo {
public static void main(String [] args) {
List<Book> all = new ArrayList<Book>();
all.add(new Book("Java",11.1));
all.add(new Book("python",22.2));
all.add(new Book("C/C++",33.3));
all.add(new Book("PHP",44.4));
// 切記:remove和contains方法需要在類中覆寫equls()類
all.remove(new Book("PHP",44.4));
System.out.println(all);
}
}
Vector子類(舊)
區別:
Vector子類採用同步處理,線程安全;而ArrayList子類則採用非線程安全的非同步處理機制。ArrayList支持Iterator、ListIterator、foreach輸出,而Vector還支持Enumeration。
總結:
- List中的數據保存順序就是數據的添加順序
- List集合中允許保存有重覆的元素
- List子介面比Collection擴充了get()、set()方法
- List大多使用ArrayList子類進行操作
Set 子介面
Set子介面只是簡單點額繼承了Collection介面,並沒有效仿List介面對原介面的功能方法進行擴充。
常見子類:HashSet、TreeSet
觀察 HashSet 子類:
public class TestDemo {
public static void main(String [] args) {
Set<String> all = new HashSet<String>();
all.add("Hello");
all.add("Hello");//不保存重覆的數據
all.add("World");
all.add("HUAWEI");
System.out.println(all + ">>>" + all.size());
}
}
通過觀察發現:Set集合下沒有重覆的數據元素(Set 子介面的特征)即:HashSet 子類特征屬於 無序排列
- 觀察 TreeSet子類:
public class TestDemo {
public static void main(String [] args) {
Set<String> all = new TreeSet<String>();
all.add("Hello");
all.add("Hello");//不保存重覆的數據
all.add("World");
all.add("Array");
System.out.println(all + ">>>" + all.size());
}
}
分析得出:TreeSet子類沒有重覆數據,以及所保存的內容預設自動升序排序。
數據排序問題
class Book implements Comparable<Book>{
private String title ;
private double price ;
public Book(String title , double price) {
this.title = title;
this.price = price;
}
@Override
public String toString() {
return this.title + "\t" + this.price;
}
/*
* 集合本質上就是動態對象數組,而動態的對象數組排序使用的是比較器
* 所以我們使用comparable比較器
*
* 由於存在重覆的元素,compareTo會認為是同一個對象,(Set子介面的特性)
* 所以 set子介面的重覆判讀就是依靠Comparable
* 為此我們可以使用String的compareTo方法進行同對象的比較
*/
@Override
public int compareTo(Book o) {
if (this.price > o.price) {
return 1;
} else if(this.price < o.price) {
return -1;
} else {
// 我們調用String類的compareTo方法來比較
return this.title.compareTo(o.title);
}
}
}
public class TestDemo {
public static void main(String [] args) {
Set<Book> all = new TreeSet<Book>();
all.add(new Book("Java",11.1));
all.add(new Book("Java",11.1)); //信息完全重覆
all.add(new Book("php",11.1)); //信息部分重覆
all.add(new Book("Python",33.3)); //信息完全不重覆
System.out.println(all);
}
}
通過觀察發現,Comparable介面支持了TreeSet類的重覆數據的判斷,並不支持對HashSet類的重覆數據的判讀
重覆元素問題
通過上述的各段代碼發現:Comparable介面(比較器)只負責對TreeSet子類的重覆元素的判斷;(依靠comparTo()方法,如若發現數據相同則判斷為是同樣的對象元素,則 return 0;)
如果要判斷數據元素的重覆,只能依靠Object中的方法:
- 取得哈希碼
public int hashCode();
- 對象比較
public boolean equals(Object obj);
代碼:
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
long temp;
temp = Double.doubleToLongBits(price);
result = prime * result + (int) (temp ^ (temp >>> 32));
result = prime * result + ((title == null) ? 0 : title.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;
Book other = (Book) obj;
if (Double.doubleToLongBits(price) != Double.doubleToLongBits(other.price))
return false;
if (title == null) {
if (other.title != null)
return false;
} else if (!title.equals(other.title))
return false;
return true;
}
總結:
在不考慮排序問題情況下,判斷元素是否重覆,依靠Object方法中的 hashCode() 和 equals()
總結:
- 在開發中,Set子介面不建議首選,如果使用也是首選建議HashSet類;
- Comparable 比較器普遍應用於Java理論中
集合輸出
Collection、List、Set三個介面,List介面是最有利於輸出操作的(ArrayList子類),故此集合的輸出:
Iterator*:迭代輸出
public interface Iterator<E> {
public boolean hasNext();
public E next<E>();
}
Iterator是一個介面,如若取得介面的實例化需要依靠Collection介面iterator()方法
public Iterator<E> iterator();// java.util.Collection
public class TestDemo {
public static void main(String [] args) {
Set<String> all = new HashSet<String>();//Set子介面
all.add("Mirror");
all.add("wangyuyang");
all.add("wangyuyang");
Iterator<String> iter = all.iterator();// 實例化介面
while (iter.hasNext()) { //判斷是否為空
String str = iter.next();// 獲取元素數據
System.out.println(str);
}
}
}
Set的特性會自動不保留重覆數據,並無序輸出
public class TestDemo {
public static void main(String [] args) {
List<String> all = new ArrayList<String>();//List子介面
all.add("Mirror");
all.add("wangyuyang");
all.add("wangyuyang");
Iterator<String> iter = all.iterator();// 實例化介面
while (iter.hasNext()) { //判斷是否為空
String str = iter.next();// 獲取元素數據
System.out.println(str);
}
}
}
顯示添加的所有元素並原樣添加的順序輸出
集合的輸出問題:
在遇到集合的輸出問題是,完全可以直接使用Iterator介面進行輸出
ListIterator:雙向迭代
Iterator本身只具備”由前向後“的輸出,而 ListLterator 子介面則支持雙向迭代。
判斷是否有前一個元素:(逆向)
public boolean hasPreviout();
- 取得前一個元素:(逆向)
public E previous();
- 實例ListIterator介面的List方法:
public ListIterator<E> listIterator();
public class TestDemo {
public static void main(String [] args) {
List<String> all = new ArrayList<String>();//Set子介面
all.add("A");
all.add("B");
all.add("C");
System.out.println("正向迭代輸出");
ListIterator<String> iter = all.listIterator();
while (iter.hasNext()) { //判斷是否為空
String str = iter.next();// 獲取元素數據
System.out.println(str);
}
System.out.println("***********");
System.out.println("逆向迭代輸出");
while(iter.hasPrevious()) {
System.out.println(iter.previous());
}
}
}
上常式序實現了雙向迭代的功能;利用hasNet()方法判斷是否為空,next()方法輸出元素內容,實現正向迭代輸出;利用ListIterator介面中的hasPrevious()和Previous()方法來實現逆向迭代輸出。
- 註意:
如果利用ListIterator介面實現逆向迭代輸出,就需要先進行正向迭代輸出;也就是說在實現逆向迭代輸出前必須實現正向迭代輸出。
Enumeration:枚舉輸出
Enumeration 和 Vector類同時發佈的輸出介面;早期的Vector類定義的集合就需要Enumeration 來輸出。
- 介面定義
public interface Enumberation<E>{
public boolean hasMoreElements(); //判斷是否有下一個元素
public E nextElement(); // 獲取當前元素內容
}
- 實例化 Enumeration介面對象,只能依靠 Vector子類
public Enumeration<E> elements() // 取得Enumeration介面對象
public class TestDemo {
public static void main(String [] args) {
Vector<String> all = new Vector<String>();//Set子介面
all.add("A");
all.add("B");
all.add("C");
Enumeration<String> enu = all.elements();
while(enu.hasMoreElements()) {
System.out.println(new String(enu.nextElement()));
}
}
}
foreach 輸出
public class TestDemo {
public static void main(String [] args) {
List<String> all = new ArrayList<String>();//Set子介面
all.add("A");
all.add("B");
all.add("C");
for (String str : all) {
System.out.println(str);
}
}
}
Map介面
Collection每次都會保存一個對象,而Map介面主要負責一對對象的信息。
主要操作方法
- 向集合中保存數據
public V put(K key , V value);
- 根據Key查找Value
public V get(Object key);
- 將Map結合轉化為Set集合
public Set<Map Entry<K,V>> entrySet();
- 取出所有Key值
public Set<K> keySet();
- 常用子類:
- HashMap
- Hashtable
觀察HashMap
public class TestDemo {
public static void main(String [] args) {
Map<String,Integer> map = new HashMap<String,Integer>();
map.put("壹", 1);
map.put("貳", 2);
map.put("叄", 3);
map.put("叄", 33);
System.out.println(map);
}
}
通過代碼分析可以發現:HashMap實現的輸出是無序的;發現的重覆的Key會進行覆蓋,使用新的內容key的value覆蓋原來的value
- get方法的應用
public class TestDemo {
public static void main(String [] args) {
Map<String,Integer> map = new HashMap<String,Integer>();
map.put("壹", 1);
map.put("貳", 2);
map.put(null, 3);
System.out.println(map.get("壹")); //返回 1
System.out.println(map.get("陸"));//key不存在返回 null
System.out.println(map.get(null));// 返回 3
}
}
通過HashMap和get()方法的代碼觀察發現,Map主要的目的是實現數據的信息的查找,Collection主要的目的是實現信息數據的輸出。
- 取得所有的key值:
public class TestDemo {
public static void main(String [] args) {
Map<String,Integer> map = new HashMap<String,Integer>();
map.put("壹", 1);
map.put("貳", 2);
map.put("叄", 3);
Set<String> set = map.keySet();// 取得key
Iterator<String> iter = set.iterator();
while(iter.hasNext()) {
System.out.println(iter.next());//輸出全部的key
}
}
}
觀察Hashtable
public class TestDemo {
public static void main(String [] args) {
Map<String,Integer> map = new Hashtable<String, Integer>();
map.put("壹", 1);
map.put("貳", 2);
map.put("叄", 3);
System.out.println(map);
}
}
通過設置key或value為Null值來比較Hashtable和HashMap兩個子類之間區別:Hashtable子類不允許存在null值,而HashMap允許Key或Value中為null值。*
Iterator輸出的問題(重點)
涉及到集合的輸出,一定要使用Iterator進行輸出;而Map介面中未定義返回Iterator介面對象的方法,故此Map數據使用Iterator輸出就需要將Map集合轉換為Set集合。
在Collection介面中,Iterator得到的是一個Collection完整的對象;而Map則不同了,但是Map.put()向集合中存一對數據的時候,會自動的封裝為Map.Entry介面對象
public static interface Map.Entry<K,V>;//(等同於一個外部介面)
- Map.Entry介面操作方法
- getkey():獲取Key值
- getValue():獲取Value值
在Map中保存的實際上是被Map.Entry介面包裝的一個對象,Map.Entry介面的對象包裝的是:Key和Value值對數據元素。
- 如上述,Iterator如取出輸出的數據實取得是一個對象(Collection介面中就是實質上取得Collection的對象),而在Map介面中,則是取出一個Map.Entry介面對象,然後在得出Key和Value。
- 在Map定義了一種將Map集合轉為Set的方法:
public Set<Map.Entry<K,V>> entrySet();
轉為Set集合後,就可以調用Iterator輸出。
利用Map介面EntrySet()方法將Map結合變為Set集合 ——> 利用Set結合中的iterator()方法將Set進行Iterator輸出 ——> 每一次取出的Set元素都是Map.Entrty介面對象,利用此對象進行Key與Value的取出
利用Iterator實現Map介面的輸出 *
public class TestDemo {
public static void main(String [] args) {
Map<String,Integer> map = new Hashtable<String, Integer>();
map.put("壹", 1);
map.put("貳", 2);
map.put("叄", 3);
// 將Map集合變為Set結合
Set<Map.Entry<String, Integer>> set = map.entrySet();
// 將Set集合實例化iterator介面對象
Iterator<Map.Entry<String, Integer>> iter = set.iterator();
while(iter.hasNext()) {
// 因為iter內容保存的是Map.Entry介面的對象,所以利用Map.Entry對象將Key和Value取出
Map.Entry<String, Integer> men = iter.next();
System.out.println(men.getKey() + "==" + men.getValue());
}
}
}
Map集合中的Key
使用的Map集合,Key的類型可以自定義;那麼這個自定義的類型必須覆寫Object類之中的hashCode() 和 equals()方法,因為只有依靠這兩個方法,才可以判斷是否元素重覆。【首先的Key類型是String,儘量不要使用自定義的對象類型去定義key;因為String類中預設了hashCode() 和 equals()】
class Book{
private String title ;
public Book(String title) {
this.title = title;
}
@Override
public String toString() {
return this.title;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((title == null) ? 0 : title.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;
Book other = (Book) obj;
if (title == null) {
if (other.title != null)
return false;
} else if (!title.equals(other.title))
return false;
return true;
}
}
public class TestDemo {
public static void main(String [] args) {
Map<Book,String> map = new HashMap<Book, String>();
map.put(new Book("java"),new String ("開發"));
System.out.println(map.get(new Book("java")));
}
}
或者:
public class TestDemo {
public static void main(String [] args) {
Map<String,Book> map = new HashMap<String, Book>();
map.put(new String ("開發"),new Book("java"));
System.out.println(map.get(new String("開發")));
}
}
public class TestDemo {
public static void main(String [] args) {
Map<String,Book> map = new HashMap<String, Book>();
map.put("開發",new Book("java"));
System.out.println(map.get("開發"));
}
}
總結
- Map集合保存數據更有利與查找,而Collection保存數據是為了輸出
- Map使用Iterator介面輸出步驟:……
- HashMap可以保存Null,Hashtable不可以保存null。
- 可以不可以重覆,一旦出現重覆會覆蓋原有內容(更新Key的Value值)
Stack子類
Stack 表示:棧操作;棧是一種先進後出的數據結構;而Stack是Vector的子類。
public class Stack<E>
extends Vector<E>
需要註意:Stack雖是Vector子類,可是不會使用Vector方法。
Stack棧操作:
- 入棧:
public E push(E item);
- 出棧:
public E pop();
- 實現入棧、出棧操作
public class TestDemo {
public static void main(String [] args) {
Stack<String> all = new Stack<String>();
all.push("A");
all.push("B");
all.push("C");
all.push("D");
System.out.println(all.pop());
System.out.println(all.pop());
System.out.println(all.pop());
System.out.println(all.pop());
}
}
如果棧中數據已經全部執行出棧而依舊繼續執行出棧pop操作,則報錯:空棧異常(棧中無數據則無法出棧執行操作)
Properties子類
Collections工具類
- 向集合中追加一組數據
public static <T> boolean addAll(Collection<E> c,……);
public class TestDemo {
public static void main(String [] args) {
List<String> all = new ArrayList<String>();
Collections.addAll(all, "A","B","C","D");
System.out.println(all);
}
}
Collections工具類是負責給集合操作介面Collection提供輔助的操作方法