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 | 同步處理,效能降低 | 執行緒安全 | 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介面簡介。ArraList,LinkedList,Vector
(一)連結串列的特點:(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介面的實現類 ArrayList,LinkedList,Vector 的區別 list實現類原始碼分析
java面試中經常被問到list常用的類以及內部實現機制,平時開發也經常用到list集合類,因此做一個原始碼級別的分析和比較之間的差異。 首先看一下List介面的的繼承關係: list介面繼承Col
Collection介面下的一些其他子類
1.LinkedHashMap LinkedHashMap繼承於HashMap,很多方法都是HashMap的方法,但是它的資料取得是有序的,即怎樣的順序插入就按怎樣的順序取出,底層用一個雙向連結串列保證有序性。 ture表示按訪問順序排序(即插入1
Android View與GroupView原理以及其子類描述
簡介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