2019-05-05

1.集合。

1.1傳統(tǒng)容器在進(jìn)行增。刪等破壞性操作時(shí),需要移動(dòng)元素,可能導(dǎo)致性能問(wèn)題,同時(shí)添加。刪除等算法和具體業(yè)務(wù)耦合在一起,增加了程序開(kāi)發(fā)的復(fù)雜度,Java集合框提供了一套性能優(yōu)良,使用方便的接口和類(lèi)。位于Java。util包。

1.2collection:他是Java集合框(collection - frame)中的頂層接口,這個(gè)接口是一個(gè)容器,容器中只能存儲(chǔ)引用數(shù)據(jù)類(lèi)型? ??建議存同一類(lèi)型的引用類(lèi)型,方便后續(xù)遍歷等操作。容器中的元素可以是有序的、可重復(fù)的,稱(chēng)為L(zhǎng)ist接口也可能是無(wú)序的、唯一的,稱(chēng)為Set接口。


1.3集合常用方法:

public?static?void?main(String[] args) {

/**

*增:add/addAll

*刪:clear/remove/removeAll/retainAll

*改:

*查:contains/containsAll/isEmpty/size

?*/

Collection?c1?= new?ArrayList();

//追加

c1.add("apple"); // Object object = new String("apple");

// c1.add(1); ?// Object object = new Integer(1);

c1.add("banana");

System.out.println(c1);

//追加一個(gè)集合

Collection?c2?= new?ArrayList();

c2.add("java");

c2.add("c++");

c1.addAll(c2);

System.out.println(c1);

// clear

//c1.clear();

// c1.remove("apple");

// c1.removeAll(c2);

//c1.retainAll(c2);

//System.out.println(c1);

System.out.println(c1.contains("apple"));

c2.add("js");

System.out.println(c1.containsAll(c2));

// c1.clear();

System.out.println(c1.isEmpty());

//返回集合元素的個(gè)數(shù)

System.out.println(c1.size());

System.out.println(c1.equals(c2));

}

1.4集合的遍歷:Iterable?可遍歷的接口,集合接口繼承于它,集合支持快速遍歷。

/快速遍歷

// for-each

// Object表示元素類(lèi)型

// item表示迭代變量

// c1表示集合

for?(Object item?: c1) {

System.out.println(item.toString());

}

快速遍歷的本質(zhì):Collection繼承Iterable接口,表示集合支持快速遍歷。Iterable接口定義了一個(gè)方法iterator()用于獲取集合的迭代器,是一個(gè)Iterator接口類(lèi)型,iterator()內(nèi)部返回一個(gè)實(shí)現(xiàn)類(lèi)實(shí)現(xiàn)類(lèi)Iterator接口。這個(gè)實(shí)現(xiàn)類(lèi)一定具有hasNext和next方法用于判斷是否有下一個(gè)元素和獲取下一個(gè)元素。快速遍歷就是基于迭代器工作的。

public?static?void?main(String[] args) {


Collection?c1?= new?ArrayList();

c1.add("apple");

c1.add("banana");

c1.add("coco");

//快速遍歷

// for-each

// Object表示元素類(lèi)型

// item表示迭代變量

// c1表示集合

for?(Object item?: c1) {

System.out.println(item.toString());

}

//迭代器遍歷(國(guó)內(nèi))

Iterator?it?= c1.iterator();

while(it.hasNext()) {

Object item?= it.next();

System.out.println(item.toString());

}

//國(guó)外

for(Iterator?it2=c1.iterator();it2.hasNext();) {

Object item?= it2.next();

System.out.println(item.toString());

}

}


1.5list接口:List?接口中的元素時(shí)有序的、可重復(fù)的。List接口中的元素通過(guò)索引(index)來(lái)確定元素的順序。有序的collection(也稱(chēng)為序列)??梢詫?duì)列表中每個(gè)元素的插入位置進(jìn)行精確地控制。用戶(hù)可以根據(jù)元素的整數(shù)索引(在列表中的位置)訪問(wèn)元素,并搜索列表中的元素

list接口常用方法:

public?static?void?main(String[] args) {

/**

*增:add/addAll/add(index,el)/addAll(index,collection)

*刪:clear/remove/removeAll/remove(index)

*改:set(index,el)

*查:get(index)/indexOf/lastIndexOf()

*其他:contains/containsAll/isEmpty/size

?*/

List?list1?= new?ArrayList();

//添加元素

list1.add("apple");

list1.add("banana");

//在指定位置添加元素

list1.add(0, "coco");

System.out.println(list1);

List?list2?= new?ArrayList();

list2.add("java");

list2.add("c++");

list1.addAll(1, list2);

System.out.println(list1);

//刪除

list1.remove(0);

System.out.println(list1);

//修改

list1.set(0, "javax");

System.out.println(list1);

//查

System.out.println(list1.get(0));

list1.add("apple");

list1.add("apple");

System.out.println(list1);

System.out.println(list1.indexOf("apple"));

System.out.println(list1.lastIndexOf("apple"));

}

list接口遍歷:ListIterator 繼承于Iterator,在Iterator的基礎(chǔ)上提供了以正向遍歷集合,也可以以逆序遍歷集合。hasNext/next 以正向遍歷,hasPrevious/previous 以逆序遍歷

public?static?void?main(String[] args) {

List?list1?= new?ArrayList();

list1.add("apple");

list1.add("banana");

list1.add("coco");

//【1】快速遍歷

System.out.println("--for each--");

for?(Object item?: list1) {

System.out.println(item.toString());

}

//【2】普通for

System.out.println("--for--");

for(int?i=0;i<list1.size();i++) {

System.out.println(list1.get(i));

}

//【3】集合迭代器

System.out.println("--iterator--");

Iterator?it?= list1.iterator();

while(it.hasNext()) {

System.out.println(it.next());

}

System.out.println("--list iterator--");

//正向遍歷

ListIterator?it2?= list1.listIterator();

while(it2.hasNext()) {

System.out.println(it2.next());

}

//逆序遍歷

while(it2.hasPrevious()) {

System.out.println(it2.previous());

}

System.out.println("--list iterator with index--");

ListIterator?it3?= list1.listIterator(1);

while(it3.hasNext()) {

System.out.println(it3.next());

}

}


1.6數(shù)據(jù)結(jié)構(gòu):數(shù)據(jù)結(jié)構(gòu)就是數(shù)據(jù)在內(nèi)存中存儲(chǔ)結(jié)構(gòu)。根據(jù)存儲(chǔ)的方式不同,分為線(xiàn)性表、二叉樹(shù)、圖、棧、隊(duì)列等

線(xiàn)表性:線(xiàn)性表數(shù)據(jù)按照一定的邏輯順序存儲(chǔ)在內(nèi)存中。線(xiàn)性表是有序的。線(xiàn)性表根據(jù)內(nèi)存的物理結(jié)構(gòu)分為兩種:數(shù)組和鏈表。

數(shù)組是一種邏輯上有序的線(xiàn)性表,物理上也連續(xù)。


鏈表是一種邏輯上有序的線(xiàn)性表,但物理上不連續(xù)。


數(shù)組和鏈表的區(qū)別


相同點(diǎn)

不同點(diǎn)


數(shù)組在查詢(xún)時(shí)效率高,在添加、刪除元素時(shí)效率低(涉及移動(dòng)元素)

鏈表在查詢(xún)時(shí)效率低(每次從頭開(kāi)始,不能跳躍訪問(wèn)),在添加、刪除元素時(shí)效率高(不涉及移動(dòng)元素)

1.7棧:特性:先進(jìn)后出,后進(jìn)先出


1.8隊(duì)列:特性:先進(jìn)先出


1.9:arraylist/vector:ArrayList是List接口的實(shí)現(xiàn)類(lèi),底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組,實(shí)現(xiàn)大小可變的數(shù)組。

ArrayList?線(xiàn)程不安全,jdk1.2


ArrayList?底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組,默認(rèn)數(shù)組大小是10,如果添加的元素個(gè)數(shù)超過(guò)默認(rèn)容量,ArrayList會(huì)自動(dòng)拓容,拓容原則:newCapacity = oldCapacity + oldCapacity / 2;

如果未來(lái)確定序列的元素不在增加,通過(guò)調(diào)用trimToSize()調(diào)制容量至合適的空間。


ArrayList作為L(zhǎng)ist接口的實(shí)現(xiàn)類(lèi),常用方法和遍歷方法參考List接口。


Vector?是List接口的實(shí)現(xiàn)類(lèi),底層數(shù)據(jù)結(jié)構(gòu)也是數(shù)組,也是大小可變的數(shù)組。

Vector是線(xiàn)程安全的,jdk1.0


Vector底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組,默認(rèn)數(shù)組大小是10,如果添加的元素個(gè)數(shù)超過(guò)默認(rèn)容量,Vector會(huì)自動(dòng)拓容,拓容原則:newCapacity = oldCapacity +capacityIncrement(增長(zhǎng)因子);如果未來(lái)確定序列的元素不在增加,通過(guò)調(diào)用trimToSize()調(diào)制容量至合適的空間。


注意:Vector在實(shí)現(xiàn)List接口的同時(shí),同添加了自身特有的方法xxxElement,未來(lái)使用時(shí)為了程序的可拓展性,一定要按照接口來(lái)操作Vector。

1.10linkedlist:LinkedList是List接口的實(shí)現(xiàn)類(lèi),底層數(shù)據(jù)結(jié)構(gòu)是鏈表。

LinekList常用方法和遍歷方法參照List接口。

LinkedList線(xiàn)程不安全。


除了實(shí)現(xiàn)List接口,還實(shí)現(xiàn)棧接口

push入棧操作/ pop出棧操作

public?class?Test01 {

public?static?void?main(String[] args) {

LinkedList?list?= new?LinkedList();

list.push("apple");

list.push("banana");

list.push("coco");

System.out.println(list.pop());

System.out.println(list.pop());

System.out.println(list.pop());

// java.util.NoSuchElementException

System.out.println(list.pop());

}

}

add/remove/element()可能會(huì)出現(xiàn)NoSuchElementException異常

public?static?void?main(String[] args) {

LinkedList?queue?= new?LinkedList();

//入隊(duì)

/**

*隊(duì)列頭 ??????????? 隊(duì)列尾

?*<----- ?????????<-----

?* [apple, banana, coco]

?*/

queue.add("apple");

queue.add("banana");

queue.add("coco");

System.out.println(queue);

//出隊(duì)

System.out.println(queue.remove());

System.out.println(queue.remove());

System.out.println(queue.remove());

System.out.println(queue);

// java.util.NoSuchElementException

System.out.println(queue.remove());

//獲取表頭元素

System.out.println(queue.element());

}

offer/poll/peek可能會(huì)返回特殊值(null)

public?static?void?main(String[] args) {

LinkedList?queue?= new?LinkedList();

//入隊(duì)

/**

*隊(duì)列頭 ??????????? 隊(duì)列尾

?*<----- ?????????<-----

?* [apple, banana, coco]

?*/

queue.offer("apple");

queue.offer("banana");

queue.offer("coco");

//出隊(duì)列

//System.out.println(queue.poll());

//System.out.println(queue.poll());

//System.out.println(queue.poll());

System.out.println(queue);


//System.out.println(queue.poll());

//獲取表頭元素

System.out.println(queue.peek());

}

雙向隊(duì)列(Deque)接口


/**

*以雙向隊(duì)列形式操作LinkedList

?*/

public?class?Test04 {

public?static?void?main(String[] args) {

LinkedList?queue?= new?LinkedList();

//入隊(duì)

/**

?*<----- ?????????<-----

?* [apple, banana, coco]

?* ---->??????????----->

?*/

queue.addFirst("apple");

queue.addFirst("banana");

queue.addFirst("coco");

System.out.println(queue);

System.out.println(queue.removeLast());

System.out.println(queue.removeFirst());

System.out.println(queue.removeFirst());

System.out.println(queue);

//獲取頭元素

System.out.println(queue.getFirst());

}

}

iterator和listitrator:Iterator在迭代過(guò)程中不允許向集合中添加元素

public?static?void?main(String[] args) {

ArrayList?list?= new?ArrayList();

list.add("apple");

list.add("banana");

list.add("coco");

Iterator?it?= list.iterator();

while(it.hasNext()) {

String item?= (String) it.next();

if(item.equals("banana")) {

list.add("test");

}

}

System.out.println(list);

}

當(dāng)通過(guò)Iterator集合迭代器遍歷集合過(guò)程中,不能再向集合匯總添加元素,否則出現(xiàn)ConcurrentModificationException并發(fā)修改異常。ListIterator允許程序員按任一方向遍歷列表、迭代期間修改列表,并獲得迭代器在列表中的當(dāng)前位置

public?class?Test01 {

public?static?void?main(String[] args) {

ArrayList?list?= new?ArrayList();

list.add("apple");

list.add("banana");

list.add("coco");

ListIterator?it?= list.listIterator();

while(it.hasNext()) {

String item?= (String) it.next();

if(item.equals("banana")) {

it.add("test");

}

}

System.out.println(list);

}

}

2.泛型:泛型允許開(kāi)發(fā)者在強(qiáng)類(lèi)型程序設(shè)計(jì)語(yǔ)言(java)編寫(xiě)代碼時(shí)定義一些可變部分,這些部分在使用前必須作出指明。泛型就是將類(lèi)型參數(shù)化

ArrayList<E> ?list表示聲明了一個(gè)列表list,列表的元素是E類(lèi)型

ArrayList<String> list = new ArrayList<String>();

聲明了一個(gè)列表list,列表的元素只能是String類(lèi)型。

泛型在編譯器起作用,運(yùn)行時(shí)jvm察覺(jué)不到泛型的存在。

2.1泛型的擦除:泛型在運(yùn)行時(shí)已經(jīng)被擦除了。

public?static?void?main(String[] args) {

ArrayList<String> list?= new?ArrayList<String>();

list.add("apple");

System.out.println(list?instanceof?ArrayList);

System.out.println(list?instanceof?ArrayList<String>);

}

Cannot perform instanceof check against parameterized type ArrayList<String>. Use the form ArrayList<?> instead since further generic type information will be erased at runtime

2.2泛型的應(yīng)用:1.泛型類(lèi):當(dāng)一個(gè)類(lèi)中屬性的數(shù)據(jù)類(lèi)型不確定時(shí),具體是什么類(lèi)型由使用者來(lái)確定時(shí),使用泛型。泛型類(lèi)的形式”

public?class 類(lèi)名<T>?{


}


定義一個(gè)泛型類(lèi)

public?class?FanClass<T> {

private?T t;


public?T getT() {

return?t;

}


public?void?setT(T t) {

this.t?= t;

}


public?FanClass(T t) {

super();

this.t?= t;

}


public?FanClass() {

super();

}

}


public?class?Test01 {

public?static?void?main(String[] args) {

FanClass<String> fan?= new?FanClass<String>();

fan.setT("apple");

FanClass<Integer> fan2?= new?FanClass<Integer>();

fan2.setT(1);

}

}

2.泛型的方法:當(dāng)一個(gè)方法的參數(shù)類(lèi)型不確定時(shí),具體是什么類(lèi)型由使用者來(lái)確定,可以考慮使用泛型方法。形式:

public?<T>?void?xxx(T?a) {

System.out.println(a);

}


public?class?Student {

/*public void showInfo(int?a) {

System.out.println(a);

}

public void showInfo(float a) {

System.out.println(a);

}

public void showInfo(String a) {

System.out.println(a);

}*/

public?<T> void?showInfo(T?a) {

System.out.println(a);

}

}


public?static?void?main(String[] args) {

Student stu?= new?Student();

stu.showInfo(1);

stu.showInfo("apple");

stu.showInfo(1.0f);

}

泛型方法在調(diào)用時(shí)確定(指明)類(lèi)型。

泛型方法在一定程度上優(yōu)化了方法重載。


泛型方法可以定義多個(gè)泛型類(lèi)型

//可以定義多個(gè)泛型的類(lèi)型

public?<A,B> void?showInfo(A?a,B b) {

System.out.println(a);

System.out.println(b);

}

多個(gè)泛型類(lèi)型進(jìn)一步優(yōu)化了方法重載。


多個(gè)同類(lèi)型的泛型

//多個(gè)同類(lèi)型的泛型

/*public <A> void print(A a) {

System.out.println(a);

}

public <A> void print(A a,A b) {

System.out.println(a);

System.out.println(b);

}*/

public?<A> void?print(A...a) {

System.out.println(a);

}

A… a 表示方法可以接受多個(gè)參數(shù)。當(dāng)調(diào)用方法傳遞多個(gè)參數(shù)時(shí),多個(gè)參數(shù)被放到a數(shù)組中,a是什么類(lèi)型的數(shù)組由開(kāi)發(fā)者調(diào)用處傳參決定。

stu.print(1);

stu.print(1,2);

stu.print("apple");

stu.print("apple","banana");

print(A...a) 方法稱(chēng)為可變參數(shù)的泛型形式。

3.泛型接口:如果接口中的方法的參數(shù)(形參、返回值)不確定時(shí),可以考慮使用泛型接口。形式

public interface FanInterface<T>?{

public void showInfo(T t);

}


[1]實(shí)現(xiàn)類(lèi)能確定泛型接口的類(lèi)型

public?class?ImplClass implements?FanInterface<String>{


@Override

public?void?showInfo(String?t) {

// TODO?Auto-generated method stub

}

}


[2]實(shí)現(xiàn)類(lèi)不能確定泛型接口的類(lèi)型->繼續(xù)泛。

public?class?ImplClass2<T> implements?FanInterface<T>{


@Override

public?void?showInfo(T t) {

}

}

4.泛型的上限和下限:泛型的上限ArrayList(? extends Pet) list 聲明了一個(gè)容器,容器中的元素類(lèi)型一定要繼承于Pet,我們稱(chēng)這種形式叫做泛型的上限。泛型的下限ArrayList(? super Pet) list 聲明了一個(gè)容器,容器中的元素類(lèi)型一定要是Pet的父類(lèi),我們稱(chēng)這個(gè)形式為泛型的下限。

3.set接口:Set接口表示一個(gè)唯一、無(wú)序的容器(和添加順序無(wú)關(guān))

3.1set接口提供的方法

public?static?void?main(String[] args) {

/**

*增:add/addAll

*刪:clear/remove/removeAll/retainAll

*改:

*查:contains/containsAll

*遍歷:iterator

*其他:size/isEmpty

?*/

Set<Integer> set?= new?HashSet<Integer>();

// [1]添加

//無(wú)序

set.add(10);

set.add(3);

set.add(20);

set.add(0);

//不能添加重復(fù)元素

boolean?r?= set.add(1);

System.out.println(set);

//【2】刪除

// set.remove(1);

// set.clear();

// System.out.println(set);

//【3】查看是否包含

System.out.println(set.contains(1));

//【4】其他

System.out.println(set.size());

System.out.println(set.isEmpty());

}

3.2set接口的遍歷:

public?static?void?main(String[] args) {

Set<String> set?= new?HashSet<String>();

set.add("banana");

set.add("apple");

set.add("coco");

//快速遍歷

for?(String item?: set) {

System.out.println(item);

}

//迭代器

Iterator<String> it?= set.iterator();

while(it.hasNext()) {

String item?= it.next();

System.out.println(item);

}

}

Set接口的實(shí)現(xiàn)類(lèi)常見(jiàn)的有HashSet、LinkedHashSet、TreeSet

3.2hashset:

ashSet是Set接口的實(shí)現(xiàn)類(lèi),底層數(shù)據(jù)結(jié)構(gòu)是哈希表。

HashSet是線(xiàn)程不安全的(不保證同步)

哈希表工作原理:


3.3添加自定義對(duì)象:

根據(jù)哈希表的工作原理,請(qǐng)存儲(chǔ)一個(gè)自定義對(duì)象到HashSet中。

package?cn.sxt03.hashset;


public?class?Student {

private?String id;

private?String name;

private?int?age;


//


@Override

public?int?hashCode() {

final?int?prime?= 31;

int?result?= 1;

result?= prime?* result?+ age;

result?= prime?* result?+ ((id?== null) ? 0 : id.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;

Student other?= (Student) obj;

if?(age?!= other.age)

return?false;

if?(id?== null) {

if?(other.id?!= null)

return?false;

} else?if?(!id.equals(other.id))

return?false;

if?(name?== null) {

if?(other.name?!= null)

return?false;

} else?if?(!name.equals(other.name))

return?false;

return?true;

}


@Override

public?String toString() {

return?"Student [id="?+ id?+ ", name="?+ name?+ ", age="?+ age?+ "]";

}


}

總結(jié)

[1]如果向HashSet中存儲(chǔ)元素時(shí),元素一定要實(shí)現(xiàn)hashCode方法和equals方法。

[2]?優(yōu)點(diǎn):添加、刪除、查詢(xún)效率高;缺點(diǎn):無(wú)序

4.linkedhashset:LinkedHashSet是Set接口的實(shí)現(xiàn)類(lèi),底層數(shù)據(jù)結(jié)構(gòu)哈希表+鏈表哈希表用于散列元素;鏈表用于維持添加順序。如果要添加自定義對(duì)象元素,也需要重寫(xiě)hashCode和equals方法。

5.treeset:TreeSet 是Set接口的實(shí)現(xiàn)類(lèi),底層數(shù)據(jù)結(jié)構(gòu)是二叉樹(shù)。TreeSet?存儲(chǔ)的數(shù)據(jù)按照一定的規(guī)則存儲(chǔ)。存儲(chǔ)規(guī)則讓數(shù)據(jù)表現(xiàn)出自然順序。

5.1treeset的工作原理:

添加一個(gè)新元素t的存儲(chǔ)的步驟

[1]?如果集合無(wú)元素,t直接加入;如果集合有元素,t和根節(jié)點(diǎn)比較;

[2] 如果t小于根節(jié)點(diǎn);把t放到根節(jié)點(diǎn)的左子樹(shù)上;重復(fù)1-3步驟

[3] t大于根節(jié)點(diǎn);把t放到根節(jié)點(diǎn)的右子樹(shù)上;重復(fù)1-3步驟


輸出時(shí)按照一定的規(guī)則:左子樹(shù)->根節(jié)點(diǎn)->右子樹(shù)


根據(jù)TreeSet的工作原理,向TreeSet添加自定義元素?

向TreeSet中添加元素時(shí),一定要提供比較策略,否則會(huì)出現(xiàn)ClassCastException。

?

比較策略分兩種:內(nèi)部比較器外部比較器

內(nèi)部比較器:當(dāng)一個(gè)自定義對(duì)象實(shí)現(xiàn)Comparable并實(shí)現(xiàn)compareTo方法時(shí),通過(guò)指定具體的比較策略,此時(shí)稱(chēng)為內(nèi)部比較器。

package?cn.sxt05.treeset;


public?class?Student implements?Comparable<Student>{

private?String id;

private?String name;

private?int?age;


// 。。


@Override

public?String toString() {

return?"Student [id="?+ id?+ ", name="?+ name?+ ", age="?+ age?+ "]";

}


@Override

public?int?compareTo(Student o) {

if(this.getAge()<o.getAge()) {

return?-1;

}else?if(this.getAge() == o.getAge()) {

return?0;

}else?{

return?1;

}

}


}

比較策略的幾種情況:1比較策略一般當(dāng)前對(duì)象寫(xiě)在前面,待比較對(duì)象也在后面,比較結(jié)果默認(rèn)升序

return??this.getAge() - o.getAge() ;

2 多種比較因素:

@Override

public?int?compareTo(Student o) {

/*if(this.getAge()<o.getAge()) {

return -1;

}else if(this.getAge() == o.getAge()) {

return 0;

}else {

return 1;

}*/

// return ?this.getAge() - o.getAge() ;

if(this.getAge()<o.getAge()) {

return?-1;

}else?if(this.getAge() == o.getAge()) {

return?this.getName().compareTo(o.getName());

}else?{

return?1;

}

}

外部比較器:當(dāng)實(shí)際開(kāi)發(fā)過(guò)程中不知道添加元素的源代碼、無(wú)權(quán)修改別人的代碼,此時(shí)可以使用外部比較器。Comparator?位于java.util包中,定義了compare(o1,o2)用于提供外部比較策略。TreeSet接受一個(gè)指定比較策略的構(gòu)造方法,這些比較策略的實(shí)現(xiàn)類(lèi)必須實(shí)現(xiàn)Comparator接口。

需求:按照字符串的長(zhǎng)度比較

public?class?Test01 {

public?static?void?main(String[] args) {

LenComparator lenComparator?= new?LenComparator();

TreeSet<String> set2?= new?TreeSet<String>(lenComparator);

set2.add("banana");

set2.add("coco");

set2.add("apple");

set2.add("apple");

System.out.println(set2);

}

}


class?LenComparator implements?Comparator<String>{


@Override

public?int?compare(String o1, String o2) {

return?o1.length() - o2.length();

}

}


使用匿名內(nèi)部類(lèi)優(yōu)化

public?class?Test02 {

public?static?void?main(String[] args) {

TreeSet<String> set2?= new?TreeSet<String>(new?Comparator<String>() {


@Override

public?int?compare(String o1, String o2) {

return?o1.length() - o2.length();

}

});

set2.add("banana");

set2.add("coco");

set2.add("apple");

set2.add("apple");

System.out.println(set2);

}

}

5.map接口:Map接口稱(chēng)為鍵值對(duì)集合或者映射集合,其中的元素(entry)是以鍵值對(duì)(key-value)的形式存在。Map?容器接口中提供了增、刪、改、查的方式對(duì)集合進(jìn)行操作。Map接口中都是通過(guò)key來(lái)操作鍵值對(duì),一般key是已知。通過(guò)key獲取value。

5.1map的常用方法:

public?static?void?main(String[] args) {

/**

*增:put/putAll

*刪:clear/remove

*改:put

*查:get/containsKey/containsValue

*其他:isEmpty/size

?*/

Map<String, String> map?= new?HashMap<String,String>();

//【1】put

map.put("A", "apple");

map.put("B", "banana");

map.put("C", "coco");

//【2】刪除

// map.clear();

// smap.remove("A");

//【3】修改

//map.put("A", "apple x");

//【4】查看

String val?= map.get("A");

System.out.println(map.containsKey("D"));

System.out.println(map);

}

5.2map的接口遍歷:

通過(guò)keySet() 返回map中鍵的set集合。

public?static?void?main(String[] args) {


Map<String, String> map?= new?HashMap<String,String>();

map.put("B", "banana");

map.put("A", "apple");

map.put("C", "coco");

// map無(wú)序

//可以根據(jù)key的自然順序 讓map有序 ?=> 一般用string作為key

System.out.println(map);

//遍歷

Set<String> keys?= map.keySet();

for?(String key?: keys) {

System.out.println(key+"=>"+map.get(key));

}

Iterator<String> it?= keys.iterator();

while(it.hasNext()) {

String key?= it.next();

System.out.println(key+"=>"+map.get(key));

}

}


map中以鍵值對(duì)作為元素,鍵值對(duì)在map中稱(chēng)為entry,entrySet返回鍵值對(duì)的set集合。

public?static?void?main(String[] args) {


Map<String, String> map?= new?HashMap<String,String>();

map.put("B", "banana");

map.put("A", "apple");

map.put("C", "coco");

// map無(wú)序

//可以根據(jù)key的自然順序 讓map有序 ?=> 一般用string作為key

System.out.println(map);

// entrySet

Set<Entry<String, String>> entrySet?= map.entrySet();

for?(Entry<String, String> entry?: entrySet) {

System.out.println(entry.getKey()+"=>"+entry.getValue());

}

Iterator<Entry<String, String>> it2?= entrySet.iterator();

while(it2.hasNext()) {

Entry<String, String> entry?= it2.next();

System.out.println(entry.getKey()+"=>"+entry.getValue());

}

}

Map接口的實(shí)現(xiàn)類(lèi)HashMap、LinkedHashMap、TreeMap

5.2hashmap:HashMap?是Map的實(shí)現(xiàn)類(lèi),key以HashSet存儲(chǔ)。

public?static?void?main(String[] args) {

/*

HashMap<String, Object> map = new HashMap<String,Object>();

ArrayList<String> list1 = new ArrayList<String>();

list1.add("alex");

list1.add("alice");

list1.add("allen");

map.put("A", list1);

ArrayList<String> list2 = new ArrayList<String>();

list2.add("ben");

list2.add("bill");

map.put("B", list2);

System.out.println(map);

*/

HashMap<Student, Object> map?= new?HashMap<Student,Object>();

ArrayList<String> list1?= new?ArrayList<String>();

list1.add("alex");

list1.add("alice");

list1.add("allen");

Student?s1?= new?Student("001", "大狗", 20);

map.put(s1, list1);

ArrayList<String> list2?= new?ArrayList<String>();

list2.add("ben");

list2.add("bill");

Student?s2?= new?Student("001", "大狗", 20);

//修改

map.put(s2, list2);

System.out.println(map);

}

總結(jié):

[1] 向HashMap中存儲(chǔ)元素時(shí),key一定要實(shí)現(xiàn)hashCode和equals

[2]?一般建議使用String作為Map接口的key

5.3linkedhashmap:LinkedHashMap是Map接口的實(shí)現(xiàn)類(lèi),key以LinkedHashSet存儲(chǔ)。

哈希表散列key,鏈表維持key的添加順序。

public?static?void?main(String[] args) {

/*LinkedHashMap<String, Object> map = new LinkedHashMap<String,Object>();

ArrayList<String> list2 = new ArrayList<String>();

list2.add("ben");

list2.add("bill");

map.put("B", list2);

ArrayList<String> list1 = new ArrayList<String>();

list1.add("alex");

list1.add("alice");

list1.add("allen");

map.put("A", list1);

System.out.println(map);*/

HashMap<Student, Object> map?= new?HashMap<Student,Object>();

ArrayList<String> list1?= new?ArrayList<String>();

list1.add("alex");

list1.add("alice");

list1.add("allen");

Student s1?= new?Student("001", "大狗", 20);

map.put(s1, list1);

ArrayList<String> list2?= new?ArrayList<String>();

list2.add("ben");

list2.add("bill");

Student s2?= new?Student("001", "大狗", 20);

//修改

map.put(s2, list2);

System.out.println(map);

}

5.4treemap:TreeMap是Map的實(shí)現(xiàn)類(lèi),key以TreeSet存儲(chǔ)。

public?static?void?main(String[] args) {

/*TreeMap<String, Object> map = new TreeMap<String,Object>(new Comparator<String>() {


@Override

public int?compare(String o1, String o2) {

return o1.length() - o2.length();

}

});

ArrayList<String> list2 = new ArrayList<String>();

list2.add("ben");

list2.add("bill");

map.put("Aa", list2);

ArrayList<String> list1 = new ArrayList<String>();

list1.add("alex");

list1.add("alice");

list1.add("allen");

map.put("B", list1);

System.out.println(map);*/

TreeMap<Student, Object> map?= new?TreeMap<Student,Object>(new?Comparator<Student>() {


@Override

public?int?compare(Student o1, Student o2) {

return?o1.getAge() - o2.getAge();

}

});

ArrayList<String> list1?= new?ArrayList<String>();

list1.add("alex");

list1.add("alice");

list1.add("allen");

Student s1?= new?Student("001", "大狗", 20);

map.put(s1, list1);

ArrayList<String> list2?= new?ArrayList<String>();

list2.add("ben");

list2.add("bill");

Student s2?= new?Student("001", "2狗", 20);

//修改

map.put(s2, list2);

System.out.println(map);

}

0.總結(jié)


0.0:collection集合具有增:add,addall;刪:remove,removeall,clear,retainall;查:size,isempty,containsall,equals,iterator。它有兩種接口,一種是list接口,一種是set接口。list接口屬于元素可重復(fù),有序的,內(nèi)含增:add,addall;刪:remove;改:set;查:get,lastindexof,sublist。set接口元素唯一,無(wú)序。

list:

1.arraylist:底層數(shù)據(jù)結(jié)構(gòu)為數(shù)組。優(yōu)點(diǎn):遍歷元素和隨機(jī)訪問(wèn)元素的效率比較高;缺點(diǎn):添加和刪除需要大量移動(dòng)元素效率低,按照內(nèi)容查詢(xún)效率低。

2.linkedlist:底層數(shù)據(jù)結(jié)構(gòu)為鏈表,優(yōu)點(diǎn):摻入刪除元素的效率比較高;缺點(diǎn):? ?遍歷訪問(wèn)元素效率較為低下。

3.vector:底層數(shù)據(jù)結(jié)構(gòu)為數(shù)組。

set:

1.hashset:底層數(shù)據(jù)結(jié)構(gòu)為hash表,無(wú)序,存儲(chǔ)到hashset中的元素必須實(shí)現(xiàn)hashcode和equals來(lái)實(shí)現(xiàn)元素的散列和去重。

2.linkedhashset:底層數(shù)據(jù)結(jié)構(gòu)為哈希表加鏈表,插入順序,存儲(chǔ)到linkedhashset中的元素必須實(shí)現(xiàn)hashcode和equals來(lái)實(shí)現(xiàn)元素的散列和去重,linkedhashset通過(guò)鏈表來(lái)維持插入順序。

treeset:底層二叉樹(shù),升序,存儲(chǔ)在treeset中的元素必須comparable接口下的comparato用于比較排序并且可以去重,當(dāng)comparable接口不能滿(mǎn)足需求時(shí),可以通過(guò)comparator接口實(shí)現(xiàn)比較排序并去重。


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容