定义一个java集合_Java集合

1.1集合框架的优点

传统的容器(数组)在进行增、删等破坏性操作时,需要移动元素,可能导致性能问题;同时添加、删除等算法和具体业务耦合在一起,增加了程序开发的复杂度。

Java集合框架提供了一套性能优良、使用方便的接口和类,它们位于java.util包中

2.2Collection

Collection是java集合框架(collection-frame)中的顶层接口。

Collection接口是一个容器,容器中只能存储引用数据类型,建议存同一类型的引用类型,方便后续遍历等操作。

容器中的元素可以是有序的、可重复的,称为List接口

也可能是无序的、唯一的,称为Set接口。

5b0b5d6f14cbd65be267f21c10441409.png

1.2.1 集合的常用方法

* 增:add/addAll

* 删:clear/remove/removeAll/retainAll

* 改:

* 查:contains/containsAll/isEmpty/size

1 public static voidmain(String[] args) {2

3 /**

4 * 增:add/addAll5 * 删:clear/remove/removeAll/retainAll6 * 改:7 * 查:contains/containsAll/isEmpty/size8 */

9

10 Collection c1 = newArrayList();11

12 //追加

13 c1.add("apple"); //Object object = new String("apple");14 //c1.add(1);//Object object = new Integer(1);

15 c1.add("banana");16 System.out.println(c1);17

18 //追加一个集合

19 Collection c2 = newArrayList();20 c2.add("java");21 c2.add("c++");22 c1.addAll(c2);23 System.out.println(c1);24

25 //clear26 //c1.clear();27

28 //c1.remove("apple");29 //c1.removeAll(c2);30 //c1.retainAll(c2);31 //System.out.println(c1);

32

33 System.out.println(c1.contains("apple"));34 c2.add("js");35 System.out.println(c1.containsAll(c2));36 //c1.clear();

37 System.out.println(c1.isEmpty());38 //返回集合元素的个数

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

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

43 }

1.2.2集合的遍历

关键字:Iterable

Iterable 可遍历的接口,集合接口继承于它,集合支持快速遍历。

//快速遍历//for-each//Object 表示元素类型//item表示迭代变量//c1表示集合

for(Object item : c1) {

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

}

快速遍历的本质

Collection继承于Iterable接口,表示集合支持快速遍历。Iterable接口定义了一个方法iterator()用于获取集合的迭代器,是一个Iterator接口类型,iterator()内部返回一个实现类实现类Iterator接口。这个实现类一定具有hasNext和next方法用于判断是否有下一个元素和获取下一个元素。快速遍历就是基于迭代器工作的。

1 public static voidmain(String[] args) {2

3

4 Collection c1 = newArrayList();5 c1.add("apple");6 c1.add("banana");7 c1.add("coco");8

9

10 //快速遍历11 //for-each12 //Object 表示元素类型13 //item表示迭代变量14 //c1表示集合

15 for(Object item : c1) {16 System.out.println(item.toString());17 }18

19 //迭代器遍历(国内)

20 Iterator it =c1.iterator();21 while(it.hasNext()) {22 Object item =it.next();23 System.out.println(item.toString());24 }25

26 //国外

27 for(Iterator it2=c1.iterator();it2.hasNext();) {28 Object item =it2.next();29 System.out.println(item.toString());30 }31 }

a214a3cf569e31b310d8d8d3024afa21.png

1.3 List接口

List 接口中的元素时有序的、可重复的。List接口中的元素通过索引(index)来确定元素的顺序。

有序的 collection(也称为序列)。可以对列表中每个元素的插入位置进行精确地控制。

用户可以根据元素的整数索引(在列表中的位置)访问元素,并搜索列表中的元素

1.3.1 List常用方法

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

删:clear/remove/removeall/remove(index)

改:set(index,el)

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

其他:contains/containsall/isEmpty/size

1 public static voidmain(String[] args) {2

3 /**

4 * 增:add/addAll/add(index,el)/addAll(index,collection)5 * 删:clear/remove/removeAll/remove(index)6 * 改:set(index,el)7 * 查:get(index)/indexOf/lastIndexOf()8 * 其他:contains/containsAll/isEmpty/size9 */

10 List list1 = newArrayList();11 //添加元素

12 list1.add("apple");13 list1.add("banana");14 //在指定位置添加元素

15 list1.add(0, "coco");16

17 System.out.println(list1);18

19 List list2 = newArrayList();20 list2.add("java");21 list2.add("c++");22

23 list1.addAll(1, list2);24 System.out.println(list1);25

26 //删除

27 list1.remove(0);28 System.out.println(list1);29

30 //修改

31 list1.set(0, "javax");32 System.out.println(list1);33

34 //查

35 System.out.println(list1.get(0));36 list1.add("apple");37 list1.add("apple");38 System.out.println(list1);39 System.out.println(list1.indexOf("apple"));40 System.out.println(list1.lastIndexOf("apple"));41 }

1.3.2 接口遍历

ListIterator继承于Iterator,在Itertaor的基础上提供了以正向遍历集合,也可以以遍历集合。

hasNext/ next 以正向 遍历

hasPrevious/previous 以遍历

【1】for each 遍历

【2】普通for遍历

【3】集合迭代器遍历

(1)正向遍历

(2)逆向遍历

1 public static voidmain(String[] args) {2

3

4 List list1 = newArrayList();5 list1.add("apple");6 list1.add("banana");7 list1.add("coco");8

9 //【1】快速遍历

10 System.out.println("--for each--");11 for(Object item : list1) {12 System.out.println(item.toString());13 }14

15 //【2】普通for

16 System.out.println("--for--");17 for(int i=0;i

21 //【3】集合迭代器

22 System.out.println("--iterator--");23 Iterator it =list1.iterator();24 while(it.hasNext()) {25 System.out.println(it.next());26 }27

28 System.out.println("--list iterator--");29 //正向遍历

30 ListIterator it2 =list1.listIterator();31 while(it2.hasNext()) {32 System.out.println(it2.next());33 }34

35 //逆序遍历

36 while(it2.hasPrevious()) {37 System.out.println(it2.previous());38 }39

40 System.out.println("--list iterator with index--");41 ListIterator it3 = list1.listIterator(1);42 while(it3.hasNext()) {43 System.out.println(it3.next());44 }45 }

d7231efde2ef40c58ed1f5356e81e30d.png

1.4 数据结构

1.4.1线性表

线性表数据按照一定的逻辑顺序存储在内存中。线性表是有序的。线性表根据内存的物理结构分为两种:数组和链表

数组是一种逻辑上有序的线性表,物理上也连续。

2d9b5796920ce80b6fc79d0c05fba75f.png

链表是一种逻辑上有序的线性表,但物理上不连续。

b030057b2291466d49fcdaf268dbdcaf.png

数组和链表的区别:

相同点:逻辑上有序

不同点:数组是物理上有序的,链表是物理上无序的。

数组在查询时效率高,在添加、删除元素时效率低(涉及移动元素)

链表在查询时效率低(每次从头开始,不能跳跃访问),在添加、删除元素时效率高(不涉及移动元素)

1.4.2 栈

特性:先进后出,后进先出

82c9ec80f494a8914b930e72cdbd4fa7.png

1.4.3 队列

特性:先进先出

4b13d62c9cf182c6ed3255eaf1db4a6c.png

1.5 ArrayList/Vector

ArayList 是List接口的实现类,底层数据结构是数组,实现大小可变的数组。

ArrayList 线程不安全,jdk1.2

ArrayList底层数据结构是数组,默认数组大小是10,如果添加的元素个数超过默认容量,

ArrayList会自动拓容,拓容原则:newCapacity = oldCapacity + oldCapacity / 2(oldCapacity>>1);

如果未来确定序列的元素不再增加,通过trimTosize()调制容量至合适的空间。

ArrayList 作为List接口的实现类,常用方法和遍历方法参考List接口。

Vector 是List接口的实现类,底层数据 结构也是数组 ,也是大小可变的数组 。

Vector是线程安全的,jdk1.0

Vector底层数据结构是数组,默认数组大小是10,

如果添加的元素个数超过默认容量,Vector会自动拓容,拓容原则:newCapacity = oldCapacity +capacityIncrement(增长因子);如果未来确定序列的元素不在增加,通过调用trimToSize()调制容量至合适的空间。

注意:Vector 在实现List接口的同时,同添加了自身特有的方法xxxElement,未来使用时为了程序的可拓展性,一定要按照接口来操作Vector。

1.6 Linkedlist

LInkedLIst是LIst接口的实现类,底层数组结构是链表。

LinkedList常用方和遍历方法参照List接口。

LinkedList线程不安全。

LinkedList坠子实现List接口,还实现栈接口。

dd88b5ca429679d96b4205a30d109d10.png

push入栈操作,pop出栈操作

1 public classTest01 {2 public static voidmain(String[] args) {3 LinkedList list = newLinkedList();4 list.push("apple");5 list.push("banana");6 list.push("coco");7

8

9 System.out.println(list.pop());10 System.out.println(list.pop());11 System.out.println(list.pop());12

13 //java.util.NoSuchElementException

14 System.out.println(list.pop());15 }16 }

队列(Queue)接口

173a593ca8370a7ab53aff1c35357637.png

add/remove/element()可能会出现NoSuchElementException异常

1 public static voidmain(String[] args) {2

3 LinkedList queue = newLinkedList();4 //入队

5 /**

6 * 队列头 队列尾7 *

10 queue.add("apple");11 queue.add("banana");12 queue.add("coco");13 System.out.println(queue);14

15 //出队

16 System.out.println(queue.remove());17 System.out.println(queue.remove());18 System.out.println(queue.remove());19 System.out.println(queue);20

21 //java.util.NoSuchElementException

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

24

25 //获取表头元素

26 System.out.println(queue.element());27 }

offer/poll/peek可能会返回特殊值(null)

1 public static voidmain(String[] args) {2

3 LinkedList queue = newLinkedList();4 //入队

5 /**

6 * 队列头 队列尾7 *

10 queue.offer("apple");11 queue.offer("banana");12 queue.offer("coco");13

14 //出队列15 //System.out.println(queue.poll());16 //System.out.println(queue.poll());17 //System.out.println(queue.poll());

18 System.out.println(queue);19

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

22 //获取表头元素

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

25 }

双向队列(Deque)接口

6032cc69853c3909d3881f6cb519ec7d.png

1 /**

2 * 以双向队列形式操作LinkedList3 */

4 public classTest04 {5 public static voidmain(String[] args) {6

7 LinkedList queue = newLinkedList();8 //入队

9 /**

10 * ----->13 */

14

15 queue.addFirst("apple");16 queue.addFirst("banana");17 queue.addFirst("coco");18 System.out.println(queue);19

20 System.out.println(queue.removeLast());21 System.out.println(queue.removeFirst());22 System.out.println(queue.removeFirst());23 System.out.println(queue);24

25 //获取头元素

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

28 }29 }

1.7 Iterator和LIstiterator

Iterator在迭代过程中不允许向集合中添加元素

Listiterator可以在迭代过程中添加元素

1 public static voidmain(String[] args) {2 ArrayList list = newArrayList();3 list.add("apple");4 list.add("banana");5 list.add("coco");6

7 Iterator it =list.iterator();8 while(it.hasNext()) {9 String item =(String) it.next();10 if(item.equals("banana")) {11 list.add("test");12 }13 }14

15 System.out.println(list);16 }

当通过Iterator集合迭代器遍历集合过程中,不能再向集合汇总添加元素,否则出现ConcurrentModificationException 并发修改异常。

ListIterator允许程序员按任一方向遍历列表、迭代期间修改列表,并获得迭代器在列表中的当前位置。

1 public classTest01 {2 public static voidmain(String[] args) {3 ArrayList list = newArrayList();4 list.add("apple");5 list.add("banana");6 list.add("coco");7

8 ListIterator it =list.listIterator();9 while(it.hasNext()) {10 String item =(String) it.next();11 if(item.equals("banana")) {12 it.add("test");13 }14 }15

16 System.out.println(list);17 }18 }

1.8 泛型(generic)

1.8.1 反省的概念

泛型允许开发者在强类型程序设计 语言(java)编写代码时定义一些可变部分,这些部分在使用前必须作出指明。

泛型就是将类型参数化。

ArrayList list 表示声明了一个列表list,列表的元素是E类型。

ArrayList list = new ArrayList();

声明了一个列表list,列表的元素只能是String类型。

泛型在编译器起作用,运行时jvm察觉不到泛型的存在。

1.8.2 泛型的擦除

泛型在运行时已经被擦除了。

1 public static voidmain(String[] args) {2 ArrayList list = new ArrayList();3 list.add("apple");4 System.out.println(list instanceofArrayList);5 System.out.println(list instanceof ArrayList);//错的表达方式

6 System.out.println(list instanceof ArrayList>);//正确的表达方式

7 }

错误时的异常:

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

1.8.3 泛型的应用

1.8.3.1 泛型类

当一个类中属性的数据类型不确定时,具体是什么类型由开发者决定,使用泛型。泛型类的形式:

public class 类名{

}

定义一个泛型类

1 public class FanClass{2 privateT t;3

4 publicT getT() {5 returnt;6 }7

8 public voidsetT(T t) {9 this.t =t;10 }11

12 publicFanClass(T t) {13 super();14 this.t =t;15 }16

17 publicFanClass() {18 super();19 }20 }

1 public classTest01 {2 public static voidmain(String[] args) {3 FanClass fan = new FanClass();4 fan.setT("apple");5

6 FanClass fan2 = new FanClass();7 fan2.setT(1);8 }9 }

1.8.3.2 泛型方法

当现代战争方法的参数 类型不确定时,具体是什么类型由使用者来确定,可以考虑使用泛型方法。

形式:

【1】把类定义成泛型类,如下:

public voidxxx(T a) {

System.out.println(a);

}

【2】

1 public classStudent {2

3

4 /*public void showInfo(int a) {5 System.out.println(a);6 }7

8 public void showInfo(float a) {9 System.out.println(a);10 }11

12 public void showInfo(String a) {13 System.out.println(a);14 }*/

15

16 public voidshowInfo(T a) {17 System.out.println(a);18 }19 }

1 public static voidmain(String[] args) {2

3 Student stu = newStudent();4 stu.showInfo(1);5 stu.showInfo("apple");6 stu.showInfo(1.0f);7 }

泛型方法在调用时确定(指明)类型。

泛型方法在一定程度上优化了方法重载。

泛型方法可以定义多个泛型类型

1 //可以定义多个泛型的类型

2 public voidshowInfo(A a,B b) {3 System.out.println(a);4 System.out.println(b);5 }

多个泛型类型进一步优化了方法重载。

多个同类型的泛型

1 //多个同类型的泛型

2 /*public void print(A a) {3 System.out.println(a);4 }5 public void print(A a,A b) {6 System.out.println(a);7 System.out.println(b);8 }*/

9

10 public voidprint(A...a) {11 System.out.println(a);12 }

A… a 表示方法可以接受多个参数。当调用方法传递多个参数时,多个参数被放到a数组中,a是什么类型的数组由开发者调用处传参决定。

1 stu.print(1);2 stu.print(1,2);3

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

print(A...a) 方法称为可变参数的泛型形式。

2.1.1.1 泛型接口(C)

如果接口中的方法的参数(形参、返回值)不确定时,可以考虑使用泛型接口。形式

1 public interface FanInterface{2

3 public voidshowInfo(T t);4

5 }

[1]实现类能确定泛型接口的类型

1 public class ImplClass implements FanInterface{2

3 @Override4

5 public voidshowInfo(String t) {6

7 //TODO Auto-generated method stub

8

9 }10

11 }

[2]实现类不能确定泛型接口的类型->继续泛。

1 public class ImplClass2 implements FanInterface{2

3 @Override4

5 public voidshowInfo(T t) {6

7

8 }9

10 }

2.1.1.2 泛型的上限和下限(C)

1 public static void print(ArrayList extends Pet>list) {2

3 for(Pet pet : list) {4

5 pet.showInfo();6

7 }8

9 }

泛型的上限ArrayList extends Pet> list 声明了一个容器,容器中的元素类型一定要继承于Pet,我们称这种形式叫做泛型的上限。

泛型的下限ArrayList super Pet> list 声明了一个容器,容器中的元素类型一定要是Pet的父类,我们称这个形式为泛型的下限。

3.1 Set接口

Set接口表示一个唯一、无序的容器(和添加顺序无关)

3.1.1 Set接口提供的方法

1 public static voidmain(String[] args) {2

3 /**

4

5 * 增:add/addAll6

7 * 删:clear/remove/removeAll/retainAll8

9 * 改:10

11 * 查:contains/containsAll12

13 * 遍历:iterator14

15 * 其他:size/isEmpty16

17 */

18

19

20

21 Set set = new HashSet();22

23 //[1]添加24

25 //无序

26

27 set.add(10);28

29 set.add(3);30

31 set.add(20);32

33 set.add(0);34

35 //不能添加重复元素

36

37 boolean r = set.add(1);38

39 System.out.println(set);40

41

42

43 //【2】删除44

45 //set.remove(1);46

47 //set.clear();48

49 //System.out.println(set);50

51

52

53 //【3】查看是否包含

54

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

57

58

59 //【4】其他

60

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

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

65 }

3.1.2 Set接口的遍历

1 public static voidmain(String[] args) {2

3

4 Set set = new HashSet();5

6 set.add("banana");7

8 set.add("apple");9

10 set.add("coco");11

12

13

14 //快速遍历

15

16 for(String item : set) {17

18 System.out.println(item);19

20 }21

22

23 //迭代器

24

25 Iterator it =set.iterator();26

27 while(it.hasNext()) {28

29 String item =it.next();30

31 System.out.println(item);32

33 }34

35 }

Set接口的实现类常见的有HashSet、LinkedHashSet、TreeSet

3.2 HashSet

HashSet是Set接口的实现类,底层数据结构是哈希表。

HashSet是线程不安全的(不保证同步)

3.2.1 哈希表工作原理

0d1aeb9bffb5200fc505627e71d44d2e.png

3.2.2 添加自定义对象

根据哈希表的工作原理,请存储一个自定义对象到HashSet中。

1 packagecn.sxt03.hashset;2

3

4

5 public classStudent {6

7 privateString id;8

9 privateString name;10

11 private intage;12

13

14

15 //…

16

17

18

19

20

21 @Override22

23 public inthashCode() {24

25 final int prime = 31;26

27 int result = 1;28

29 result = prime * result +age;30

31 result = prime * result + ((id == null) ? 0: id.hashCode());32

33 result = prime * result + ((name == null) ? 0: name.hashCode());34

35 returnresult;36

37 }38

39

40

41 @Override42

43 public booleanequals(Object obj) {44

45 if (this ==obj)46

47 return true;48

49 if (obj == null)50

51 return false;52

53 if (getClass() !=obj.getClass())54

55 return false;56

57 Student other =(Student) obj;58

59 if (age !=other.age)60

61 return false;62

63 if (id == null) {64

65 if (other.id != null)66

67 return false;68

69 } else if (!id.equals(other.id))70

71 return false;72

73 if (name == null) {74

75 if (other.name != null)76

77 return false;78

79 } else if (!name.equals(other.name))80

81 return false;82

83 return true;84

85 }86

87

88

89 @Override90

91 publicString toString() {92

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

95 }96

97

98

99 }

总结

[1]如果向HashSet中存储元素时,元素一定要实现hashCode方法和equals方法。

[2] 优点:添加、删除、查询效率高;缺点:无序

3.3 LinkedHashSet

LinkedHashSet是Set接口的实现类,底层数据结构哈希表+链表

哈希表用于散列元素;链表用于维持添加顺序。

如果要添加自定义对象元素,也需要重写hashCode和equals方法。

3.4 TreeSet

TreeSet 是Set接口的实现类,底层数据结构是二叉树。

TreeSet 存储的数据按照一定的规则存储。存储规则让数据表现出自然顺序。

3.4.1 TreeSet工作原理

8e8954c3d5ffc46297c5b0696abb78ca.png

添加一个新元素t的存储的步骤:

[1] 如果集合无元素,t直接加入;如果集合有元素,t和根节点比较;

[2] 如果t小于根节点;把t放到根节点的左子树上;重复1-3步骤

[3] t大于根节点;把t放到根节点的右子树上;重复1-3步骤

输出时按照一定的规则:左子树->根节点->右子树

根据TreeSet的工作原理,向TreeSet添加自定义元素?

向TreeSet中添加元素时,一定要提供比较策略,否则会出现ClassCastException。

比较策略分两种:内部比较器和外部比较器

3.4.2 内部比较器

当一个自定义对象实现Comparable并实现compareTo方法时,通过指定具体的比较策略,此时称为内部比较器。

1 packagecn.sxt05.treeset;2

3

4

5 public class Student implements Comparable{6

7 privateString id;8

9 privateString name;10

11 private intage;12

13

14

15 //。。。

16

17

18

19 @Override20

21 publicString toString() {22

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

25 }26

27

28

29 @Override30

31 public intcompareTo(Student o) {32

33 if(this.getAge()

35 return -1;36

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

39 return 0;40

41 }else{42

43 return 1;44

45 }46

47 }48

49

50

51 }

比较策略的几种情况

[1]比较策略一般当前对象写在前面,待比较对象也在后面,比较结果默认升序

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

如果想要降序,改变两个比较对象的位置即可。

[2] 多种比较因素

1 @Override2

3 public intcompareTo(Student o) {4

5 /*if(this.getAge()

7 return -1;8

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

11 return 0;12

13 }else {14

15 return 1;16

17 }*/

18

19

20

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

22

23

24 if(this.getAge()

26 return -1;27

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

30 return this.getName().compareTo(o.getName());31

32 }else{33

34 return 1;35

36 }37

38 }

3.4.3 外部比较器

当实际开发过程中不知道添加元素的源代码、无权修改别人的代码,此时可以使用外部比较器。

Comparator 位于java.util包中,定义了compare(o1,o2) 用于提供外部比较策略。

TreeSet接受一个指定比较策略的构造方法,这些比较策略的实现类必须实现Comparator

接口。

需求:按照字符串的长度比较

1 public classTest01 {2

3 public static voidmain(String[] args) {4

5

6 LenComparator lenComparator = newLenComparator();7

8 TreeSet set2 = new TreeSet(lenComparator);9

10

11

12 set2.add("banana");13

14 set2.add("coco");15

16 set2.add("apple");17

18 set2.add("apple");19

20 System.out.println(set2);21

22

23

24 }25

26 }27

28

29 class LenComparator implements Comparator{30

31

32

33 @Override34

35 public intcompare(String o1, String o2) {36

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

39 }40

41 }

使用匿名内部类优化

1 public classTest02 {2

3 public static voidmain(String[] args) {4

5

6 TreeSet set2 = new TreeSet(new Comparator() {7

8

9 @Override10

11 public intcompare(String o1, String o2) {12

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

15 }16

17

18 });19

20 set2.add("banana");21

22 set2.add("coco");23

24 set2.add("apple");25

26

27 set2.add("apple");28

29 System.out.println(set2);30

31

32 }33

34 }

3.5 Map接口

Map接口称为键值对集合或者映射集合,其中的元素(entry)是以键值对(key-value)的形式存在。

Map 容器接口中提供了增、删、改、查的方式对集合进行操作。

Map接口中都是通过key来操作键值对,一般key是已知。通过key获取value。

3.5.1 map常用方法

1 public static voidmain(String[] args) {2

3

4

5 /**

6

7 * 增:put/putAll8

9 * 删:clear/remove10

11 * 改:put12

13 * 查:get/containsKey/containsValue14

15 * 其他:isEmpty/size16

17 */

18

19

20

21 Map map = new HashMap();22

23

24

25 //【1】put

26

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

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

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

33

34

35 //【2】删除36

37 //map.clear();38

39 //map.remove("A");40

41

42

43 //【3】修改44

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

47

48

49 //【4】查看

50

51 String val = map.get("A");52

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

55

56

57

58

59 System.out.println(map);60

61 }

3.5.2 map接口的遍历

通过keySet() 返回map中键的set集合。

1 public static voidmain(String[] args) {2

3

4

5 Map map = new HashMap();6

7

8

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

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

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

15 //map无序16

17 //可以根据key的自然顺序 让map有序 => 一般用string作为key

18

19 System.out.println(map);20

21

22

23

24

25 //遍历

26

27 Set keys =map.keySet();28

29 for(String key : keys) {30

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

33 }34

35

36 Iterator it =keys.iterator();37

38 while(it.hasNext()) {39

40 String key =it.next();41

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

44 }45

46 }

map中以键值对作为元素,键值对在map中称为entry,entrySet返回键值对的set集合。

1 public static voidmain(String[] args) {2

3

4

5 Map map = new HashMap();6

7

8

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

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

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

15 //map无序16

17 //可以根据key的自然顺序 让map有序 => 一般用string作为key

18

19 System.out.println(map);20

21

22 //entrySet

23

24 Set> entrySet =map.entrySet();25

26 for (Entryentry : entrySet) {27

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

30 }31

32

33 Iterator> it2 =entrySet.iterator();34

35 while(it2.hasNext()) {36

37 Entry entry =it2.next();38

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

41 }42

43 }

Map接口的实现类HashMap、LinkedHashMap、TreeMap

3.6 HashMap

HashMap 是Map的实现类,key以HashSet存储。

1 public static voidmain(String[] args) {2

3

4

5 /*

6

7 HashMap map = new HashMap();8

9

10

11 ArrayList list1 = new ArrayList();12

13 list1.add("alex");14

15 list1.add("alice");16

17 list1.add("allen");18

19 map.put("A", list1);20

21

22

23

24

25 ArrayList list2 = new ArrayList();26

27 list2.add("ben");28

29 list2.add("bill");30

31 map.put("B", list2);32

33

34

35 System.out.println(map);36

37 */

38

39

40

41

42

43 HashMap map = new HashMap();44

45

46

47 ArrayList list1 = new ArrayList();48

49 list1.add("alex");50

51 list1.add("alice");52

53 list1.add("allen");54

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

57 map.put(s1, list1);58

59

60

61 ArrayList list2 = new ArrayList();62

63 list2.add("ben");64

65 list2.add("bill");66

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

69 //修改

70

71 map.put(s2, list2);72

73 System.out.println(map);74

75

76

77 }

总结:

[1] 向HashMap中存储元素时,key一定要实现hashCode和equals(用于去重,用以符合哈希表工作原理)

[2] 一般建议使用String作为Map接口的key

3.7 LinkedHashMap

LinkedHashMap是Map接口的实现类,key以LinkedHashSet存储。

哈希表散列key,链表维持key的添加顺序。

1 public static voidmain(String[] args) {2

3 /*LinkedHashMap map = new LinkedHashMap();4

5 ArrayList list2 = new ArrayList();6

7 list2.add("ben");8

9 list2.add("bill");10

11 map.put("B", list2);12

13

14

15 ArrayList list1 = new ArrayList();16

17 list1.add("alex");18

19 list1.add("alice");20

21 list1.add("allen");22

23 map.put("A", list1);24

25

26

27 System.out.println(map);*/

28

29

30 HashMap map = new HashMap();31

32 ArrayList list1 = new ArrayList();33

34 list1.add("alex");35

36 list1.add("alice");37

38 list1.add("allen");39

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

42 map.put(s1, list1);43

44

45

46 ArrayList list2 = new ArrayList();47

48 list2.add("ben");49

50 list2.add("bill");51

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

54 //修改

55

56 map.put(s2, list2);57

58 System.out.println(map);59

60

61

62 }

1.8 TreeMap

TreeMap是Map的实现类,key以TreeSet存储。

1 public static voidmain(String[] args) {2

3

4

5

6

7 /*TreeMap map = new TreeMap(new Comparator() {8

9

10

11 @Override12

13 public int compare(String o1, String o2) {14

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

17 }18

19 });20

21

22

23 ArrayList list2 = new ArrayList();24

25 list2.add("ben");26

27 list2.add("bill");28

29 map.put("Aa", list2);30

31

32

33 ArrayList list1 = new ArrayList();34

35 list1.add("alex");36

37 list1.add("alice");38

39 list1.add("allen");40

41 map.put("B", list1);42

43

44

45 System.out.println(map);*/

46

47

48

49

50

51

52

53 TreeMap map = new TreeMap(new Comparator() {54

55

56

57 @Override58

59 public intcompare(Student o1, Student o2) {60

61 return o1.getAge() -o2.getAge();62

63 }64

65 });66

67

68

69 ArrayList list1 = new ArrayList();70

71 list1.add("alex");72

73 list1.add("alice");74

75 list1.add("allen");76

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

79 map.put(s1, list1);80

81

82

83 ArrayList list2 = new ArrayList();84

85 list2.add("ben");86

87 list2.add("bill");88

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

91 //修改

92

93 map.put(s2, list2);94

95 System.out.println(map);96

97

98

99 }

1.9 总结

a846e92462b3e8b600290a43b2c8e4de.png

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值