1. 程式人生 > >List介面與Set介面及其子類的詳細用法。Collection介面簡介。ArraList,LinkedList,Vector

List介面與Set介面及其子類的詳細用法。Collection介面簡介。ArraList,LinkedList,Vector

(一)連結串列的特點:
(1)這種節點關係的處理操作,核心需要一個Node類(儲存資料,設定引用)
(2)在進行連結串列資料的查詢,刪除的時候需要equals()方法的支援。
在實際的開發中對於這些資料的使用都有一些共性的特點:儲存進去而後取。
     
     
   (二)Java類集框架
   1 Collection集合介面  
 (1)具體內容
  在java的類集裡面(java.util包)提供兩個最為核心的操作介面:Collection,Map介面,
其中Collection介面的操作與之前編寫連結串列操作的形式類似,每進行一次資料操作的時候只能對單個物件進行處理。
所以Collection是單個集合儲存的最大父介面。 Collection介面定義如下:
public interface Collection<E>extends Iterable<E>
從jdk1.5開始發現Collection介面上追加有泛型應用,這樣的直接好處就是可以避免了ClassCastException,裡面的所有的
資料的儲存型別應該是相同的。


Iterabl介面中有方法  +iterable():Iterable<T>
Collection介面中有方法   public boolean add(E e)//向集合中新增資料
                        public boolean addAll(Collection<?extends E>c)//向集合中新增一組資料
                        public void clear() //清空集合資料
                        public boolean contains(Object o) //查詢資料是否存在,需要使用equals()
                        public boolean remove(Object o)//刪除資料,需要equals方法
                        public int size()//取得集合長度
                        public Object[] toArray()//將集合變為物件陣列返回
                        public Iterator<E>iterator()//取得Iterator介面物件,用於輸出
                                              重點看第一個和最後一個方法
Collection介面中有List介面(允許重複)和Set介面(不允許重複)這兩個子介面。還有就是Set介面並沒有對Collection介面進行擴充。List介面進行了擴充。
(2)List介面
在實際開發專案中,優先考慮List集合介面 。其中的一些重要方法:
public E get(int index)//根據索引取得儲存的資料                  
public E set(int index,E element)//修改資料
List子介面和Collection介面的最大特點在於其有一個get()方法,可以根據索引取得內容。而List本身還屬於一個介面,如果想要取得介面的例項化物件,就必須有子類。
List介面下有三個常用子類:ArrayList,Vector,LinkedList.




(3)ArrayList類
ArrayList是一個針對於List介面的陣列操作實現。
示例:
public class Test {


	public static void main(String[] args) throws Exception {
		List<String> all=new ArrayList<>();//此集合中只允許儲存String資料型別
		System.out.println(all.size()+","+all.isEmpty());//看集合目前的大小以及是否為空
		all.add("hellow");
		all.add("hellow");//重複輸入
		all.add("world");
		all.remove("hellow");//	刪除資料,需要equals方法
		System.out.println(all.size()+","+all.isEmpty());//看集合目前的大小以及是否為空
		System.out.println(all.contains("ABC"));//查詢資料是否存在,需要使用equals()
		System.out.println(all.contains("world"));//查詢資料是否存在,需要使用equals()
		System.out.println(all);
		
	}


}



輸出結果0,true
2,false
false
true
[hellow, world]
  所以也證明了List介面允許重複。






(4)觀察List的get操作
public class Test {


	public static void main(String[] args) throws Exception {
		List<String> all=new ArrayList<>();//此集合中只允許儲存String資料型別		
		all.add("hellow");
		all.add("hellow");//重複輸入
		all.add("world");
		for(int x=0;x<all.size();x++)
		{
			System.out.println(all.get(x));
		}
		
		
	}


}


結果如下:
hellow
hellow
world


注意:get方法是List子介面的,如果現在使用的不是List而是Collection,那麼對於此時的資料取出你只能將集合變為物件來取出。
示例:用Collection介面進行資料的輸出(儘量不用這種操作)
public class Test {


	public static void main(String[] args) throws Exception {
		Collection<String> all=new ArrayList<>();//此集合中只允許儲存String資料型別,注意list是collection的子介面,ArrayList是List子類		
		all.add("hellow");
		all.add("hellow");//重複輸入
		all.add("world");
		//操作一object的形式返回,那麼就有可能向下轉型,可能造成安全隱患
	Object [] result=all.toArray();//變為object物件陣列
	System.out.println(Arrays.toString(result));
			}
}



(5)List與簡單java類。
下面的這個例子在實際開發中出現的機率是很低的
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;


class Person
{
     private String name;
     private Integer age;//Integer和int最大的區別在於前者能為空
     public Person(String name,Integer age)
     {
    	    this.name=name;
            this.age=age;
     }
     
     public boolean equals(Object obj)
     {
    	 if(this==obj)
    	 {
    		 return true;
    	 }
    	 if(obj==null)
    	 {
    		 
    		 return false;
    	 }
    	 if(!(obj instanceof Person))
    	 {
    		 return false;
    	 }
    	 Person per=(Person)obj;//這個地方可以向下轉型
    	 return this.name.equals(per.name)&&this.age.equals(per.age);
     }


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


}


public class Test {


	public static void main(String[] args) throws Exception {
		List<Person> all=new ArrayList<>();
		all.add(new Person("張三",12));
		all.add(new Person("李四",11));
		all.add(new Person("王五",18));
		//對於集合中的remove(),contains()方法必須類中有equals的支援。
		/*
		 *   public boolean contains(Object o) //查詢資料是否存在,需要使用equals()
             public boolean remove(Object o)//刪除資料,需要equals方法
		 */
		all.remove(new Person("張三",12));
       System.out.println(all.contains(new Person("李四",11)));
		for(int x=0;x<all.size();x++)
		{
			System.out.println(all.get(x));
			
		}
		
	}


}


結果如下:
true
Person [name=李四,age=11]
Person [name=王五,age=18]


(6)
Vector類與ArrayList類的區別(在用法上,就是將ArrayList換成Vector即可)
    處理形式   資料安全                輸出形式
Vector   同步處理,效能降低執行緒安全  Iterator,ListIterator,foreach,
ArrayList 非同步處理,效能更高        非執行緒安全        Iterator,ListIterator,foreach
                                     
  (7)Linkedlsit類與ArrayList區別(在實際開發中,Linkedlsit的用法就是將ArrayList進行替換即可)
  ① ArrayList中放的是陣列,如果在例項化此類物件的時候,預設傳入了陣列的大小(List<Person> all=new ArrayList<>(2);),則裡面儲存的陣列就會開闢一個定長的陣列。
    但是如果後面再進行資料儲存的時候發現數組的個數不夠了,那麼會進行陣列的動態擴充。如果要使用ArrayList最好的做法就是設定初始化的大小。以分頁的程式為例,
    每次只會取出指定行的內容。
 ② Linkedlsit是一個純粹的連結串列實現。
總結:ArrayList封裝的是一個數組,Linkedlsit封裝的是一個連結串列實現。ArrayList的時間複雜度為1,因為能通過索引直接定位,而Linkedlsit時間複雜度為n。
    開發之中考慮的是ArrayList,如果考慮效能,一定要傳入初始化大小。






(8)set介面
   ① Collection介面中有List介面(允許重複)和Set介面(不允許重複)這兩個子介面。還有就是Set介面並沒有對Collection介面進行擴充。List介面進行了擴充。
     在set介面中不能用get方法。在set介面中有兩個常用的子類:HashSet(無序儲存),TreeSet(有序儲存)。
   ② 示例: 觀察HashSet的使用

public class Test {


	public static void main(String[] args) throws Exception {
		Set<String> all=new HashSet<>();
		all.add("hellow");
		all.add("hellow");
		all.add("world");
		System.out.println(all);
	
	
	}
}


結果是:[hellow, world]。可以看出set介面是不允許重複 的。














示例:TreeSet的使用


public class Test {


	public static void main(String[] args) throws Exception {
		Set<String> all=new TreeSet<>();
		all.add("c");
		all.add("c");//重複
		all.add("a");
		all.add("b");
		all.add("d");
		System.out.println(all);
	}
}



結果是:[a, b, c, d]   可以看出TreeSet的結果是按照升序排列的。set介面是不允許重複的。






(9)TreeSet排序分析
示例:
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
//.java中可以有多個類,但是隻能有一個public公共類。
//
class Person 
{
	private String name;
	private Integer age;
	public Person(String name,Integer age)
	{
		this.name=name;
		this.age=age;
	}
	//一般這個方法使用來把其他型別的資料轉為字串型別的資料的。
	public String toString()
	{
		return "Person name="+this.name+",age="+this.age+"\n";
	}
	
}


public class Test {


	public static void main(String[] args) throws Exception {
	Set<Person> set=new TreeSet<>();
	set.add(new Person("張三",23));
	set.add(new Person("張三",23));//重複資料
	set.add(new Person("李四",23));//年齡重複
	set.add(new Person("王五",29));
	System.out.println(set);
	
	}
}


結果是:Exception in thread "main" java.lang.ClassCastException: 類集概述及相關集合介面.Person cannot be cast to java.lang.Comparable
at java.util.TreeMap.compare(TreeMap.java:1188)
at java.util.TreeMap.put(TreeMap.java:531)
at java.util.TreeSet.add(TreeSet.java:255)
at 類集概述及相關集合介面.Test.main(Test.java:29)
可以通過TreeSet實現資料的排列處理操作,但是在這個例子中,若進行資料的排序,實際上是針對物件陣列進行的排序,若要進行物件陣列的排序,那麼物件所在的類一定要
實現Comparable介面,重寫compareTo()方法。因為只有通過此方法才能知道大小關係。
改正後:
import java.util.Set;
import java.util.TreeSet;
//.java中可以有多個類,但是隻能有一個public公共類。
//
class Person implements Comparable<Person>
{
	private String name;
	private Integer age;
	public Person(String name,Integer age)
	{
		this.name=name;
		this.age=age;
	}
	//一般這個方法使用來把其他型別的資料轉為字串型別的資料的。
	public String toString()
	{
		return "Person name="+this.name+",age="+this.age+"\n";
	}
	//這時候要對所有的屬性進行比較
	public int compareTo(Person o)
	{
		if(this.age>o.age)
		{
			return 1;
		}else if(this.age<o.age)
		{
			return -1;
		}else
		{
			return this.name.compareTo(o.name);
		}
	}
}


public class Test {


	public static void main(String[] args) throws Exception {
	Set<Person> set=new TreeSet<>();
	set.add(new Person("張三",23));
	set.add(new Person("張三",23));//重複資料
	set.add(new Person("李四",23));//年齡重複
	set.add(new Person("王五",29));
	System.out.println(set);
	
	}
}


結果:[Person name=張三,age=23
, Person name=李四,age=23
, Person name=王五,age=29
]
用TreeSet進行排序要對所有的屬性進行比較,所以太麻煩了。set介面不允許重複。


(10)使用HashSet類時判斷重複元素需要依靠Object類中的兩個方法:
hash碼:public int hashCode();
物件比較:public boolean equals(Object obj)
在java中進行物件比較的操作需要兩步:第一步,通過一個物件的唯一編碼找到一個物件的資訊,當編碼匹配之後再呼叫equals()方法進行內容的比較。
需要注意的是hashCode和equals方法都可以通過在source中找到generate hashCode()和equals()自動生成這兩個方法。
如果想要標識出物件的唯一性,一定需要hashCode和equals這兩個方法。


import java.util.HashSet;
import java.util.Set;
import java.util.TreeSet;
//.java中可以有多個類,但是隻能有一個public公共類。
//
class Person implements Comparable<Person>
{
	private String name;
	private Integer age;
	public Person(String name,Integer age)
	{
		this.name=name;
		this.age=age;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((age == null) ? 0 : age.hashCode());
		result = prime * result + ((name == null) ? 0 : name.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;
		Person other = (Person) obj;
		if (age == null) {
			if (other.age != null)
				return false;
		} else if (!age.equals(other.age))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}


  //一般這個方法使用來把其他型別的資料轉為字串型別的資料的。
	public String toString()
	{
		return "Person name="+this.name+",age="+this.age+"\n";
	}
	//這時候要對所有的屬性進行比較
	public int compareTo(Person o)
	{
		if(this.age>o.age)
		{
			return 1;
		}else if(this.age<o.age)
		{
			return -1;
		}else
		{
			return this.name.compareTo(o.name);
		}
	}


	
}


public class Test {


	public static void main(String[] args) throws Exception {
	Set<Person> set=new HashSet<>();
	set.add(new Person("張三",23));
	set.add(new Person("張三",23));//重複資料
	set.add(new Person("李四",23));//年齡重複
	set.add(new Person("王五",29));
	System.out.println(set);
	
	}
}


結果:[Person name=張三,age=23
, Person name=李四,age=23
, Person name=王五,age=29
]


總結:在很多時候使用Set集合的核心目的不是讓其進行排序,而是讓其進行重複元素的過濾,那麼使用treeset就沒有意義。
但是重複元素需要依靠hashCode和equals兩個方法消除,所以如果不是必須的時候,在使用set介面的時候儘量使用系統提供的類實現,例如String,Integer。


可以借鑑的原則:(1)儲存自定義類物件時一定用List介面。(2)儲存系統類的資訊的時候一定用Set介面。

相關推薦

List介面Set介面及其詳細用法Collection介面簡介ArraListLinkedListVector

(一)連結串列的特點:(1)這種節點關係的處理操作,核心需要一個Node類(儲存資料,設定引用)(2)在進行連結串列資料的查詢,刪除的時候需要equals()方法的支援。在實際的開發中對於這些資料的使用都有一些共性的特點:儲存進去而後取。             (二)Jav

Java 集合-Set接口及其

允許 ret ins ict amp println out ++ || 2017-10-31 19:20:45 Set:無序且唯一 實現子類:HashSet, HashSet 此類實現 Set 接口,由哈希表(實際上是一個 HashMap 實例)支持。它不保

27-集合--Set及其(HashSet+LinkedHashSet+TreeSet)+二叉樹+Comparable+Comparator+雜湊表+HashSet儲存自定義物件+判斷元素唯一的方式

一、Set 1、Set:元素不可以重複,是無序的(存入和取出的順序不一致) 2、Set介面中的方法和Collection中的方法一致 3、Set集合的元素取出方式只有一種:迭代器iterator() Set set = new HashSet(); I

Set集合及其集合HashSet 、LinkedHashSet、TreeSet;Map集合及其集合HashMap、Hashtable;Collections(集合工具);IO概述和異常

Set集合 TreeSet的排序例項 需求:儲存自定義物件到TreeSet集合中,並遍歷 package OBT; public class Student implements Comparable<Student>{ String

java中List介面的實現 ArrayListLinkedListVector 的區別 list實現原始碼分析

java面試中經常被問到list常用的類以及內部實現機制,平時開發也經常用到list集合類,因此做一個原始碼級別的分析和比較之間的差異。 首先看一下List介面的的繼承關係: list介面繼承Col

Collection介面下的一些其他

1.LinkedHashMap LinkedHashMap繼承於HashMap,很多方法都是HashMap的方法,但是它的資料取得是有序的,即怎樣的順序插入就按怎樣的順序取出,底層用一個雙向連結串列保證有序性。 ture表示按訪問順序排序(即插入1

Android ViewGroupView原理以及其描述

簡介View是Android UI元件的基類,ViewGroup是容納UI元件的容器,ViewGroup本身也是從View派生出來的。簡單的說,Android UI介面是由View和ViewGroup及其派生類組合而成的,其結構示意圖:下面將簡單的介紹View與GroupVi

為什麼不通過修改介面或者選擇書寫繼承介面重寫方法的新偏偏選擇新增上一個裝飾器

為什麼不通過修改介面或者選擇書寫繼承介面的新子類,偏偏選擇新增上一個裝飾器?   1.盆友們,其實這個問題挺簡單的,還記得單純我們為啥選擇定義介面呀抽象類呀(這些框架、模板的)嗎? 大白話--“方便批量生產”+ “不破壞原有類結構”。(最後會放上介面和繼承重寫的作用的哈) 記住“方便批量生產” +

SRS學習筆記10-SrsConnection及其分析

when red ins parse discovery bsp for port std SrsConnection類代表一個client的連接,其中封裝了st thread,用於在一個單獨的st thread裏處理一個client的服務請求. SrsConnection

UI組件之AdapterView及其(四)Gallery畫廊控件使用

convert cal instance ram scaletype 循環 reat targe 外觀 聽說 Gallery如今已經不使用了,API使用ViewPaper取代了,以後再學專研ViewPaper吧如今說說Gallery畫廊,就是不停顯示圖片的意思 Gall

UI組件:TextView及其

時間 raw 界面 realtime 字體 框圖 相對 mage 導入   TextView(文本框)   一、TextView作用類似於JLable用於在界面上顯示文本    二、TextView沒有邊框,如果需要邊框可以導入背景框的圖片,背景框可以自定義為背景顏色漸變

UI組件:ImageView及其

button 聯系人 round span 按鈕 界面 bad -a color   ImageView     用於顯示所有Drawable對象  ImageButton(圖片按鈕) 註意點:和Button的區別是:Button可以顯示文字,而ImageButton不

Scope及其介紹

AR ica oat 元素 equal mco ans font style 之前寫的文章: 關於作用域範圍Scope Scope及相關的子類如下: 同時有些Scope還繼承了Scope.ScopeListener類,如下: 1、StarImportSco

scrapy spider及其

level __init__ 常用 mit read none them csv sna 1.spider傳參   在運行 crawl 時添加 -a 可以傳遞Spider參數: scrapy crawl myspider -a category=electronics

阻塞佇列BlockingQueue及其的使用

     BlockingQueues在java.util.concurrent包下,提供了執行緒安全的佇列訪問方式,當阻塞佇列插入資料時,如果佇列已經滿了,執行緒則會阻塞等待佇列中元素被取出後在插入,當從阻塞佇列中取資料時,如果佇列是空的,則執行緒會阻塞等待佇列中有新元素。本文詳細介紹了BlockingQu

Java中Map集合及其

Collection集合的特點是每次進行單個物件的儲存,如果現在要進行一對物件的儲存,就只能用Map集合來完成,即Map集合中會一次性儲存兩個物件,且這兩個物件的關係:key = value結構。這種結構的最大特點是可以通過key找到對應的value內容。1.Map介面Map

Java向上轉型向下轉型(的物件賦給父的)

一.定義:    通俗理解向上轉型:    就是子類轉型成父類。   classA   {   }   classBextendsA   {   }   A b=new B();   這個就是向上轉型。   向上轉型可以像下面這條語句這麼簡單:   Shape s =new Circle();   這裡,建

List 泛型,傳遞引數為,呼叫方法接收為父問題總結

list<子類> child list<父類> fatherpublic void xxx(? extends list<父類>){} 呼叫方法接受引數為list<父類>,public void xxx(? extends

Android Activity原理以及其描述

簡介         Activity是Android應用程式元件,實現一個使用者互動視窗,我們可以實現佈局填充螢幕,也可以實現懸浮視窗。一個app由很多個Actvitiy組合而成,它們之間用intent-filter區別主次關係。下面將簡單介紹Activity以及其子類和其

UIView及其

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override poin