2019-05-05

1.集合哼勇。

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

1.2collection:他是Java集合框(collection - frame)中的頂層接口渴庆,這個(gè)接口是一個(gè)容器铃芦,容器中只能存儲(chǔ)引用數(shù)據(jù)類型? ??建議存同一類型的引用類型雅镊,方便后續(xù)遍歷等操作。容器中的元素可以是有序的刃滓、可重復(fù)的仁烹,稱為L(zhǎng)ist接口也可能是無序的、唯一的注盈,稱為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表示元素類型

// item表示迭代變量

// c1表示集合

for?(Object item?: c1) {

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

}

快速遍歷的本質(zhì):Collection繼承Iterable接口,表示集合支持快速遍歷胧砰。Iterable接口定義了一個(gè)方法iterator()用于獲取集合的迭代器鳍鸵,是一個(gè)Iterator接口類型,iterator()內(nèi)部返回一個(gè)實(shí)現(xiàn)類實(shí)現(xiàn)類Iterator接口尉间。這個(gè)實(shí)現(xiàn)類一定具有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表示元素類型

// 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接口中的元素通過索引(index)來確定元素的順序眠副。有序的collection(也稱為序列)画切。可以對(duì)列表中每個(gè)元素的插入位置進(jìn)行精確地控制囱怕。用戶可以根據(jù)元素的整數(shù)索引(在列表中的位置)訪問元素霍弹,并搜索列表中的元素

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ǔ)的方式不同耍缴,分為線性表、二叉樹挽霉、圖防嗡、棧、隊(duì)列等

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

數(shù)組是一種邏輯上有序的線性表硅蹦,物理上也連續(xù)荣德。


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


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


相同點(diǎn)

不同點(diǎn)


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

鏈表在查詢時(shí)效率低(每次從頭開始,不能跳躍訪問)署咽,在添加近顷、刪除元素時(shí)效率高(不涉及移動(dòng)元素)

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


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


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

ArrayList?線程不安全慕匠,jdk1.2


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

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


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


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

Vector是線程安全的,jdk1.0


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


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

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

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

LinkedList線程不安全枢泰。


除了實(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在迭代過程中不允許向集合中添加元素

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)通過Iterator集合迭代器遍歷集合過程中,不能再向集合匯總添加元素衡蚂,否則出現(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.泛型:泛型允許開發(fā)者在強(qiáng)類型程序設(shè)計(jì)語言(java)編寫代碼時(shí)定義一些可變部分年叮,這些部分在使用前必須作出指明具被。泛型就是將類型參數(shù)化

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

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

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

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

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.泛型類:當(dāng)一個(gè)類中屬性的數(shù)據(jù)類型不確定時(shí),具體是什么類型由使用者來確定時(shí)爆存,使用泛型衬横。泛型類的形式”

public?class 類名<T>?{


}


定義一個(gè)泛型類

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ù)類型不確定時(shí),具體是什么類型由使用者來確定终蒂,可以考慮使用泛型方法蜂林。形式:

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í)確定(指明)類型。

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


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

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

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

System.out.println(a);

System.out.println(b);

}

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


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

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

/*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是什么類型的數(shù)組由開發(fā)者調(diào)用處傳參決定。

stu.print(1);

stu.print(1,2);

stu.print("apple");

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

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

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

public interface FanInterface<T>?{

public void showInfo(T t);

}


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

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


@Override

public?void?showInfo(String?t) {

// TODO?Auto-generated method stub

}

}


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

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


@Override

public?void?showInfo(T t) {

}

}

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

3.set接口:Set接口表示一個(gè)唯一、無序的容器(和添加順序無關(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]添加

//無序

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)類常見的有HashSet某筐、LinkedHashSet比搭、TreeSet

3.2hashset:

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

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

哈希表工作原理:


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):添加盗冷、刪除、查詢效率高;缺點(diǎn):無序

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

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

5.1treeset的工作原理:

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

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

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

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


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


根據(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í)卑笨,通過指定具體的比較策略,此時(shí)稱為內(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ì)象寫在前面,待比較對(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í)際開發(fā)過程中不知道添加元素的源代碼近迁、無權(quán)修改別人的代碼,此時(shí)可以使用外部比較器簸州。Comparator?位于java.util包中鉴竭,定義了compare(o1,o2)用于提供外部比較策略歧譬。TreeSet接受一個(gè)指定比較策略的構(gòu)造方法,這些比較策略的實(shí)現(xiàn)類必須實(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)部類優(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接口稱為鍵值對(duì)集合或者映射集合瑰步,其中的元素(entry)是以鍵值對(duì)(key-value)的形式存在。Map?容器接口中提供了增璧眠、刪缩焦、改、查的方式對(duì)集合進(jìn)行操作责静。Map接口中都是通過key來操作鍵值對(duì)袁滥,一般key是已知。通過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的接口遍歷:

通過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無序

//可以根據(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中稱為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無序

//可以根據(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)類HashMap、LinkedHashMap熄赡、TreeMap

5.2hashmap:HashMap?是Map的實(shí)現(xiàn)類猾普,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)類初家,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)類溜在,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接口元素唯一芙粱,無序。

list:

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

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

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

set:

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

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

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


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市口注,隨后出現(xiàn)的幾起案子变擒,更是在濱河造成了極大的恐慌,老刑警劉巖疆导,帶你破解...
    沈念sama閱讀 216,997評(píng)論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赁项,死亡現(xiàn)場(chǎng)離奇詭異葛躏,居然都是意外死亡澈段,警方通過查閱死者的電腦和手機(jī)悠菜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,603評(píng)論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來败富,“玉大人悔醋,你說我怎么就攤上這事∈薅#” “怎么了芬骄?”我有些...
    開封第一講書人閱讀 163,359評(píng)論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)鹦聪。 經(jīng)常有香客問我账阻,道長(zhǎng),這世上最難降的妖魔是什么泽本? 我笑而不...
    開封第一講書人閱讀 58,309評(píng)論 1 292
  • 正文 為了忘掉前任淘太,我火速辦了婚禮,結(jié)果婚禮上规丽,老公的妹妹穿的比我還像新娘蒲牧。我一直安慰自己,他們只是感情好赌莺,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,346評(píng)論 6 390
  • 文/花漫 我一把揭開白布冰抢。 她就那樣靜靜地躺著,像睡著了一般艘狭。 火紅的嫁衣襯著肌膚如雪挎扰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,258評(píng)論 1 300
  • 那天巢音,我揣著相機(jī)與錄音鼓鲁,去河邊找鬼。 笑死港谊,一個(gè)胖子當(dāng)著我的面吹牛骇吭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播歧寺,決...
    沈念sama閱讀 40,122評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼燥狰,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了斜筐?” 一聲冷哼從身側(cè)響起龙致,我...
    開封第一講書人閱讀 38,970評(píng)論 0 275
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎顷链,沒想到半個(gè)月后目代,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,403評(píng)論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,596評(píng)論 3 334
  • 正文 我和宋清朗相戀三年榛了,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了在讶。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,769評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡霜大,死狀恐怖构哺,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情战坤,我是刑警寧澤曙强,帶...
    沈念sama閱讀 35,464評(píng)論 5 344
  • 正文 年R本政府宣布,位于F島的核電站途茫,受9級(jí)特大地震影響碟嘴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜囊卜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,075評(píng)論 3 327
  • 文/蒙蒙 一娜扇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧边败,春花似錦袱衷、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,705評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至排截,卻和暖如春嫌蚤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背断傲。 一陣腳步聲響...
    開封第一講書人閱讀 32,848評(píng)論 1 269
  • 我被黑心中介騙來泰國(guó)打工脱吱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人认罩。 一個(gè)月前我還...
    沈念sama閱讀 47,831評(píng)論 2 370
  • 正文 我出身青樓箱蝠,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親垦垂。 傳聞我的和親對(duì)象是個(gè)殘疾皇子宦搬,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,678評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容