1. 程式人生 > >數據結構-List接口-LinkedList類-Set接口-HashSet類-Collection總結

數據結構-List接口-LinkedList類-Set接口-HashSet類-Collection總結

public 位置 end 簡介 無需 collect 保持 fin pop

一.數據結構:4種--<需補充>
1.堆棧結構:
特點:LIFO(後進先出);棧的入口/出口都在頂端位置;壓棧就是存元素/彈棧就是取元素;
代表類:Stack;
其它:main方法最後一個出去;
2.數組結構:
特點:一片連續的空間;有索引,查找快;增刪慢;
代表類:ArrayList;
應用場景:用於查詢多的場景,如天氣預報;
3.隊列結構:
特點:FIFO(先進先出);入口/出口在兩側;
代表:Queue接口
應用場景:12306購票網站
4.鏈表結構:
特點:增刪快,查詢慢;
代表:LinkedList類;Linked開頭的都是鏈表結構.
應用場景:比如監控;歷史操作/日誌;

二.List接口:(java.util)
定義:public interface List<E> extends Collection<E>{}
List接口屬於Collection的子接口之一,Collection中的所有方法,List接口的對象都能用.
特點:有序,帶索引,允許重復,可以存放多個null值;
常用子類:ArrayList;LinkedList;
常用方法:
public void add(int index,E element){}在指定位置增加元素;
public boolean addAll(int index, Collection<? extends E> c){}在指定位置增加一組元素;
E get(int index){}返回指定位置的元素;
public int indexOf(Object o){}查找指定元素的位置;
public int lastIndexOf(Object o){}從後向前查找指定元素的位置;
public ListIterator<E> listIterator(){}為ListIterator實例化;
public E remove(int index){}按指定的位置刪除元素;
public List<E> subList(intFromIndex, intToIndex){}取出集合中的子集合;
public E set(int index, E element){}替換指定位置的元素;

代碼演示://ListIterator

  1 /*List額外提供了一個ListIterator,在Iterator的基礎上增加了三個方法
  2 1.boolean hasPrevious():返回與叠代器關聯的集合是否還有上一個元素;
  3 2.Object previous():返回叠代器的上一個元素;
  4 3.void add(Object o):在指定位置插入一個元素;*/
  5 
  6 import java.util.List;
  7  import java.util.ArrayList;
  8  import java.util.ListIterator;
  9  public
class ListIteratorDemo{ 10 public static void main(String[] args){ 11 String[] names = {"jack","rose","tom"}; 12 List<String> list = new ArrayList<>(); 13 for(int i = 0; i < names.length; i++){ 14 list.add(names[i]); 15 } 16 ListIterator<String> lit = list.listIterator(); 17 //向後叠代 18 while(lit.hasNext()){ 19 System.out.print(lit.next()+"\t");//jack rose tom 20 } 21 System.out.println("\n=====下面反向叠代=========="); 22 //向前叠代 23 while(lit.hasPrevious()){ 24 System.out.print(lit.previous()+"\t");//tom rose jack 25 } 26 } 27 } 28


三.LinkedList類:(java.util)
定義:public class LinkedList<E> extends AbstractSequentialList<E> implements List<E>, Deque<E>, Cloneable, Serializable
是List接口的實現類;
特點:LinkedList中數據存儲結構為鏈表結構,但是也允許將鏈表結構作為隊列/雙端隊列/堆棧使用;
構造方法:
LinkedList()
LinkedList(Collection<? extends E> c);復制集合時,可利用該構造方法直接將集合放進去即可;
特有方法:
public void addFirst():添加至0位置;
public void addLast():等同於add,添加至最後;
E getFirst():返回集合中第一個元素;
E getLast():返回集合中最後一個元素;
E removeFirst():刪除並返回第一個元素;
E removeLast();刪除並返回最後一個元素;(由於這兩個remove才會想到使用LinkedList);
E poll():找到並刪除表頭;作為堆棧使用,類似於removeFirst;
E pollFirst():刪除並返回第一個元素;
E pollLast():刪除並返回最後一個元素;
E pop():作為堆棧使用,類似於removeFirst()
E push():作為堆棧使用,類似於addFirst()

代碼演示:// offer()/offerFirst()/push()/peekFirst()/peekLast() /pop()/pollLast()

  1  import java.util.LinkedList;
  2 
  3      public class LinkedListDemo{
  4          public static void main(String[] args){
  5              LinkedList<String> books = new LinkedList<>();
  6              //將字符串元素加入隊列的尾部
  7             books.offer("java講義");
  8              //將字符串元素加入隊列的頭部
  9             books.offerFirst("android 講義");
 10              //將字符串元素加入棧的頂部
 11             books.push("java ee 講義");
 12 
 13              //以list方式(索引)遍歷集合元素
 14             for(int i = 0; i < books.size(); i++){
 15                  System.out.println("遍歷中:"+books.get(i));
 16              }
 17 
 18              //訪問不刪除棧頂的元素
 19             System.out.println(books.peekFirst());//java ee 講義---push
 20              //訪問不刪除隊列的最後一個元素
 21             System.out.println(books.peekLast());//java講義--offer
 22              //將棧頂的元素彈出
 23             System.out.println(books.pop());//java ee  講義--push
 24              //下面將看到隊列中第一個元素被刪除
 25             System.out.println(books);//[android 講義, java講義]
 26              //訪問並刪除隊列中的最後一個元素
 27             System.out.println(books.pollLast());//java講義--offer
 28              System.out.println(books);//[android 講義]
 29          }
 30      }

四.Set接口:(java.util)
定義:public interface Set<E> extends Collection<E>{} 所以Collection中的大多數方法,均能使用;
特點:無序,大多數不帶索引,不允許重復,只能包含一個null值;
set並沒有對Collection接口進行擴充,只是比Collection接口的要求列加嚴格了,不能增加重復元素;
常用子類:
TreeSet:
HashSet:
LinkedHashSet:相對於HashSet集合來說,保證了存與取的順序一致

五.HashSet類:(java.util)
定義:public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, Serializable
特點:不能放重復元素,采用散列的存儲方式.
對存進去的每一個元素,都使用一個hash算法,進行運算,得出hash碼值;根據hash碼值決定保存元素的位置;
註意:(農/豐)(兒/女)哈希值相等
哈希表:
1.簡介:Hash table,也叫哈希表,是根據關鍵碼值(Key value)而直接進行訪問的數據結構。也就是說,
它通過把關鍵碼值映射到表中一個位置來訪問記錄,以加快查找的速度。這個映射函數叫做散列函數,存放記錄的數組叫做散列表。
2.初衷:hash表的初衷希望每個位置都保存一個元素,以提升查詢的性能!
3.Obect類中提供了一個HashCode方法,該方法可以得到一個對象的hash碼值;
4.常規協定:
(1)如果根據equals(Object)方法,兩個對象是相等的,那麽他們的hash value必須相等.
(2)如果根據equals(Object)方法,兩個對象是不相等,那麽他們的hash value也可能相等.
(3)在Java應用程序執行期間,在對同一對象多次調用hashCode方法時,必須一致地返回相同的整數.
(4)從某一應用程序的一次執行到同一應用程序的另一次執行,hash value無需保持一致。
構造方法:
HashSet()
HashSet(Collection<? extends E> c)
HashSet存自定義數據類型:
如果set集合中存自定義數據類型的對象,建議重寫equals方法和hashCode方法,否則,當兩個對象的屬性值完全相同時,會保存兩個對象!與set集合規則沖突.

代碼重寫示例:

  1 /*class中僅包含兩個屬性:private String name; private int age;hashCode()和equals()方法重寫如下*/
  2          @Override
  3          public int hashCode(){
  4              final int prime = 31;
  5              int result = 1;
  6              result = prime * result + age;
  7              result = prime * result + ((name == null) ? 0 : name.hashCode());
  8              return result;
  9          }
 10 
 11          @Override
 12          public boolean equals(Object obj){
 13              if (this == obj)
 14                  return true;
 15              if (obj == null)
 16                  return false;
 17             if (getClass() != obj.getClass())
 18                  return false;
 19              Person other = (Person) obj;
 20              if (age != other.age)
 21                  return false;
 22              if (name == null) {
 23                  if (other.name != null)
 24                      return false;
 25              } else if (!name.equals(other.name))
 26                  return false;
 27              return true;
 28          }

六.判斷元素唯一性的規則
1.list判斷元素唯一性的規則(相關方法:remove,contains):
僅僅依賴equals方法的結果;與是否重寫hashCode方法沒有任何關系;
2.set判斷元素唯一性的規則:(相關方法:add,remove,contains)
(1)先判斷兩個對象的hash值是否相同;
1.1:兩個對象的hash值不相同,不再進行任何判斷,直接得出結論,這兩個對象不相等!
1.2:兩個對象的hash值相同,繼續進行第二步比較;
(2)判斷兩個對象的equals方法是否相同;
2.1:兩個對象的equals方法不相同,得出結論,這兩個對象不相等!
2.2:兩個對象的equals方法相同,得出結論,這兩個對象相等!
代碼演示:

  1 import java.util.HashSet;
  2      //類A的equals()方法總是返回true,僅重寫equals()
  3      class A{
  4          public boolean equals(Object o){
  5              System.out.println("=====A euqals()======");
  6              return true;
  7          }
  8      }
  9 
 10      //類B的hashCode()總是返回1,僅重寫hashCode()
 11      class B{
 12          public int hashCode(){
 13              System.out.println("=======B hashCode()========");
 14              return 1;
 15          }
 16      }



  1 //重寫euqals()和hashCode()
  2      class C{
  3          public int hashCode(){
  4              System.out.println("=======C hashCode()========");
  5              return 2;
  6          }
  7          public boolean equals(Object o){
  8              System.out.println("=====C equals()======");
  9              return true;
 10          }
 11      }


  1  //測試
  2     public class HashSetTest{
  3          public static void main(String[] args){
  4              HashSet books = new HashSet();
  5              /*A僅重寫了equals(),添加第二個A時,結果:A作為兩個對象保存[[email protected], [email protected]],並且未調用equals()方法.說明首先調用hashCode(),如果不相等,則直接認為是兩個對象
  6             並提示:註: HashSetTest.java使用了未經檢查或不安全的操作。*/
  7              books.add(new A());
  8              books.add(new A());
  9 
 10              //B僅重寫了hashCode(),添加第二個B時,結果:B作為兩個對象保存[[email protected], [email protected]],並提示:註: HashSetTest.java使用了未經檢查或不安全的操作。
 11             books.add(new B());
 12              books.add(new B());
 13 
 14              //C重寫了euqals()和hashCode(),添加第二個C時,結果作為一個對象保存[[email protected]],註: HashSetTest.java使用了未經檢查或不安全的操作。
 15             C c1 = new C();    //僅運行這一行,不調用hashCode()
 16              C c2 = new C();
 17              books.add(c1);
 18              books.add(c2);
 19              System.out.println(books);
 20          }
 21      }

輸出:[-----------OUTPUT-----------
=======B hashCode()========//添加B時調用一次
=======B hashCode()========//第二次添加B時調用一次
=======C hashCode()========//第一次添加C時調用一次
=======C hashCode()========//第二次添加C時調用一次
=====C equals()======//第二次添加C時調用比較
=======B hashCode()========//輸出第一個B時,調用hashCode()
=======B hashCode()========//輸出第二個B時,調用hashCode()
=======C hashCode()========//輸出C時,調用hashCode()
[[email protected], [email protected], [email protected], [email protected], [email protected]]]

七.Collection總結:
Collection:
|- List 可以存儲重復元素,有序的(元素存取順序)
|- ArrayList
|- LinkedList
|- Set 不能存儲重復元素,無序的(元素存取順序)
|- HashSet
|- LinkedHashSet
Collection方法:
? boolean add(Object e) 把給定的對象添加到當前集合中
? void clear() 清空集合中所有的元素
? boolean remove(Object o) 把給定的對象在當前集合中刪除
? boolean contains(Object o) 判斷當前集合中是否包含給定的對象
? boolean isEmpty() 判斷當前集合是否為空
? Iterator iterator() 叠代器,用來遍歷集合中的元素的
? int size() 返回集合中元素的個數
? Object[] toArray() 把集合中的元素,存儲到數組中
? Iterator : 叠代器
? Object next()返回叠代的下一個元素
? boolean hasNext()如果仍有元素可以叠代,則返回 true。
List與Set集合的區別?
List:
它是一個有序的集合(元素存與取的順序相同)
它可以存儲重復的元素
Set:
它是一個無序的集合(元素存與取的順序可能不同)
它不能存儲重復的元素
List集合中的特有方法
? void add(int index, Object element) 將指定的元素,添加到該集合中的指定位置上
? Object get(int index)返回集合中指定位置的元素。
? Object remove(int index) 移除列表中指定位置的元素, 返回的是被移除的元素
? Object set(int index, Object element)用指定元素替換集合中指定位置的元素,返回值的更新前的元素
ArrayList:
底層數據結構是數組,查詢快,增刪慢
線程不安全,效率高
LinkedList:
底層數據結構是鏈表,查詢慢,增刪快
線程不安全,效率高
泛型:用來約束數據的數據類型
? 泛型的格式:
<數據類型>
泛型可以使用在 類,接口,方法,變量上
? 泛型的好處
A:提高了程序的安全性
B:將運行期遇到的問題轉移到了編譯期
C:省去了類型強轉的麻煩
增強for:簡化數組和Collection集合的遍歷
格式:
for(元素數據類型 變量 : 數組或者Collection集合) {
使用變量即可,該變量就是元素
}
好處:簡化遍歷
HashSet:
元素唯一不能重復
底層結構是:哈希表結構
元素的存與取的順序不能保證一致
如何保證元素的唯一的?重寫hashCode() 與 equals()方法
LinkedHashSet:
元素唯一不能重復
底層結構是:哈希表結構 + 鏈表結構
元素的存與取的順序一致

數據結構-List接口-LinkedList類-Set接口-HashSet類-Collection總結