關於java集合的初步理解
一。 集合初始:
為什麼要用集合:
面向物件的語言對事物的具體體現都是以事物的形式。
為了方便對多個物件的操作,就要對物件進行儲存,另一方面,使用陣列儲存物件具有一些弊端,而集合就像是一種容器,可以動態的把多個物件的引用放入容器。
說到這裡,不得不說一下陣列的侷限性:
1。陣列只能透過下標操作儲存的元素
2。陣列的記憶體空間是連續分佈的,而集合的記憶體空間不一定連續分佈
3。陣列的長度是固定的,長度的改變會產生新的陣列,集合的長度是動態可變的,改變長度不會產生新的集合。
4。陣列能儲存引用資料和基本資料,集合只能存引用資料,集合更適合引用資料的具體操作
5。陣列只能存一種型別的資料,而集合可以新增多種型別的資料
2。 集合的用途
用於儲存數量不等的多個物件,還可以儲存具有對映關係的關聯陣列
3。 集合的類別:
單列集合Collection介面和雙列集合Map介面
1。 Collection介面:分為Set介面和List介面
2。 Map介面:具有對映關係的 key————value 對的集合
二。 Collection介面:
1。 Collection介面繼承樹
2。 Collection介面的方法:
1.
Collection 介面是List、Set 和Queue 介面的父介面,該接口裡定義的方法既可用於操作Set 集合,也可用於操作List 和Queue 集合。
2.
JDK不提供此介面的任何直接實現,而是提供更具體的子介面實現。
3.
Collection集合的遍歷
//遍歷Collection集合建立迭代器物件 集合。iterator();
Collectionc2 =
new
ArrayList();
c2。add(“1”);
c2。add(“12”);
c2。add(“123”);
c2。add(“1234”);
Iteratori = c2。iterator();
//在呼叫i。next()方法之前必須要呼叫 i。hasNext()方法進行判斷
while
(i。hasNext()) {//判斷是否還有下一個元素 有向下進行
System。
out
。print(i。next()+“ ”);//取出當前的元素 指標下移
}
//迭代的過程不能對集合進行增刪操作
System。
out
。println();
System。
out
。println(c2);
//遍歷 增強for迴圈 內部 不能對迭代器進行增刪操作
out
(Object o:c2) {
System。
out
。print(o+“ ”);
}
out
Iterator:
1。Iterator物件稱為迭代器(設計模式的一種),主要用於遍歷Collection 集合中的元素。
2。所有實現了Collection介面的集合類都有一個iterator()方法,用以返回一個實現了Iterator介面的物件。
3。Iterator 僅用於遍歷集合,Iterator 本身並不提供承裝物件的能力。如果需要建立Iterator 物件,則必須有一個被迭代的集合。
注意:迭代器只能用於遍歷,不能用於集合元素的增刪,否者會發生ConcurrentModificationException異常,在用foreach和Iterator時都有可能發生。
for
Collection介面的子介面
1。 List介面:
1。 特點:
有序且可以重複
取代陣列儲存資料的侷限性
可以根據序號索引存取容器的元素
常用類ArrayList LinkedList Vector
2。 方法:
out
out
4.
5.
void add(intindex, Object ele)
booleanaddAll(int index, Collection eles)
Objectget(int index)
intindexOf(Object obj)
3。 類:
ArrayList:底層是陣列結構,本質上是物件引用的一個可變長的陣列
LinkedList:底層是連結串列結構
注意:ArrayList查詢快 LinkedList增刪快,對於頻繁使用增刪操作的建議使用LinkedList
4。 程式碼:
intlastIndexOf(Object obj)
Objectremove(int index)
TestList {
Object set(int index, Object ele)
List subList(int fromIndex, int toIndex)
public
main(String[] args) {
//< >之間放的是泛型 一般是引用資料型別
ArrayList list =
class
ArrayList();
//將陣列轉換為集合
public
[] arr = {1,2,3,4};
//陣列的工具類Arrays
List<
static
[]> arrlist = Arrays。
void
(arr);
new
(
int
i = 0; i < arrlist。size(); i++) {
int
(
asList
j = 0; j < arrlist。get(i)。length; j++) {
//陣列轉化為集合相當於將陣列當做一個元素放入集合中
for
p = arrlist。get(i)[j];
System。
int
。println(p);
}
}
LinkedListlinklist =
for
LinkedList<>();
linklist。add(1);
linklist。add(12);
linklist。add(16);
System。
int
。println(list);
linklist。addFirst(15);
System。
int
。println(list);
linklist。addLast(30);
System。
out
。println(list);
out
x = linklist。removeLast();//移出最後一個數據
System。
new
。println(x);
}
}
2。 Set介面:
1。 特點:
沒有提供額外的方法
自動去重,元素無序
根據equals()方法判斷元素是否相同
2。 類:
HashSet:
HashSet是Set介面的典型實現,大多數的時候使用Set集合時都會使用這個集合
HashSet的底層實現是根據Hashcode來儲存集合中的元素的,具有很好的存取和查詢功能
特點:無序,不是執行緒安全的,集合元素可以為null
注意:當向HashSet 集合中存入一個元素時,HashSet 會呼叫該物件的hashCode() 方法來得到該物件的hashCode 值,然後根據hashCode 值決定該物件在HashSet 中的儲存位置。
out
out
:兩個物件透過hashCode() 方法比較相等,並且兩個物件的equals() 方法返回值也相等
如果兩個元素的equals() 方法返回true,但它們的hashCode() 返回值不相等,hashSet 將會把它們儲存在不同的位置,但依然可以新增成功。
out
out
out
out
重寫hashCode()方法的
int
在程式執行時,同一個物件多次呼叫hashCode() 方法應該返回相同的值
當兩個物件的equals()方法比較返回true 時,這兩個物件的hashCode() 方法的返回值也應相等
物件中用作equals()方法比較的Field,都應該用來計算hashCode 值
3。 程式碼:
out
out
TestSetColleation {
HashSet
集合判斷兩個元素相等的標準
對於存放在Set
main(String[] args) {
//HashSet集合的特點 無序且不重複
HashSet
容器中的物件,對應的類一定要重寫equals()
HashSet
set。add(1);
set。add(2);
//不允許重複
//如果set集合發現重複 就會覆蓋重複值
set。add(1);//有重複 覆蓋重複值
set。add(3);
System。
和hashCode(Object obj)
。println(set);
//HasdCode Hash值是有一定的範圍的
//自動裝箱
Integer i = Integer。
方法,以實現物件相等規則。
(1);
基本原則:
hash1 = i。hashCode();//算出Hash值
Integer j = Integer。
public
(101);
class
hash2 = j。hashCode();
public
(hash1 == hash2) {
//呼叫 equals()方法 多個物件呼叫同一個雜湊值 比較物件的內容是否一致
System。
static
。println(“jjj”);
//如果equals方法返回true則進行覆蓋
}
void
{
System。
new
。println(1332);
}
//無序的
HashSet
out
HashSet
set2。add(“我”);
set2。add(“是”);
set2。add(“誰”);
System。
out
。println(“我”。hashCode());
System。
valueOf
。println(“是”。hashCode());
System。
int
。println(“誰”。hashCode());
System。
valueOf
。println(set2);
int
();
}
/**
* 從1 23 4 5 6 7 8 9 找出所有符合
*123 + 456 = 789
* 用 set集合
*/
if
out
out
test() {
//
else
自動生成的方法存根
out
sum = 0;
out
count = 0;
new
(
out
i = 100; i < 1000; i++) {
out
(
out
j = 999; j >=i; j——) {
out
[] arr =
out
out
[9];
HashSet
out
HashSet
sum = i + j;
out
(sum<1000) {
//找到每個位的數字
arr[0] = i%10;
arr[1] = i/10%10;
arr[2] = i/100;
arr[3] = j%10;
arr[4] = j/10%10;
arr[5] = j/100;
arr[6] = sum%10;
arr[7] = sum/10%10;
arr[8] = sum/100;
//判斷0
test
(
private
k = 0; k < arr。length; k++) {
static
(arr[k] != 0) {
set。add(arr[k]);
void
(set。size()==arr。length) {
count++;
System。
TODO
。println(i+“+”+j+“=”+sum);
}
}
}
}
}
}
System。
int
。println(count);
}
}
LinkedHashSet:HashSet的子類,有序不允許重複,底層是連結串列結構和Set結構
TreeSet:
TreeSet有兩種排序方法:
自然排序:(預設)
TreeSet 會呼叫集合元素的compareTo(Object obj) 方法來比較元素之間的大小關係,然後將集合元素按升序排列
定製排序:
如果試圖把一個物件新增到TreeSet時,則該物件的類必須實現Comparable 介面。
實現Comparable的類必須實現compareTo(Object obj) 方法,兩個物件即透過compareTo(Object obj) 方法的返回值來比較大小。
注意:
向TreeSet 中新增元素時,只有第一個元素無須比較compareTo()方法,後面新增的所有元素都會呼叫compareTo()方法進行比較。
int
for
對於TreeSet 集合而言,它判斷兩個物件是否相等的唯一標準是:兩個物件透過compareTo(Object obj) 方法比較返回值
當需要把一個物件放入TreeSet 中,重寫該物件對應的equals() 方法時,應保證該方法與compareTo(Object obj) 方法有一致的結果:如果兩個物件透過equals() 方法比較返回true,則透過compareTo(Object obj) 方法比較應返回0
程式碼:
int
for
TestTreeSet {
int
int
new
main(String[] args) {
TreeSet
int
TreeSet
//新增物件
t。add(
new
TestTreeSet_test(1,2));
t。add(
if
TestTreeSet_test(0,9));
t。add(
for
TestTreeSet_test(3,4));
System。
int
。println(t);
TreeSet
if
TreeSet
//新增int資料
t2。add(2);
t2。add(5);
t2。add(3);
t2。add(9);
t2。add(6);
System。
if
。println(t2);
}
}
out
TestTreeSet_test
out
Comparable
out
x,y;
out
TestTreeSet_test() {}
因為只有相同類的兩個例項才會比較大小,所以向TreeSet
TestTreeSet_test(
中新增的應該是同一個類的物件
x,
public
y) {
class
。x = x;
public
。y = y;
}
@Override
static
void
compareTo(Object o) {
new
(o
new
TestTreeSet_test) {
TestTreeSet_test t = (TestTreeSet_test) o;
new
(
new
。x>t。x) {
out
1;
}
out
{
new
-1;
}
}
out
0;
}
@Override
out
String toString() {
class
“x=”+x+“ y=”+y;
}
}
三。 Map介面:請待下回分解