Collection
概述
在 java.util.Collection 中。是层级结构中的根接口,表示一组对象。Collection 是接口,但是在 JDK 中不提供此接口的任何实现,它提供了更为具体的子接口(如 Set,List)
Collection常用方法
集合中的 contains,remove 方法等涉及到对象比较的方法,都是用对象的 equals 方法。如果对象没有重写equals 方法,那么默认的 equals 方法的作用和 == 是一样的,都是比较对象的地址。
1. 添加
add(object obj): 一个添加一个元素
addAll(Collection other): 一次添加多个元素。理解为并集
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| package com.itguigu.collection;
import java.util.ArrayList; import java.util.Collection;
import org.junit.Test;
public class TestConlection { @Test public void test1() { Collection arrayList = new ArrayList(); arrayList.add("张三"); arrayList.add("李四"); Collection other = new ArrayList(); other.add("王五"); other.add("赵六"); arrayList.addAll(other); System.out.println(arrayList.size()); } }
|
2. 删除
remove(object obj): 一次移出一个元素
removeAll(Collection other):一个移出多个元素。理解为移出多个相同的元素。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| package com.itguigu.collection;
import java.util.ArrayList; import java.util.Collection;
import org.junit.Test;
public class TestConlection { @Test public void test1() { Collection arrayList = new ArrayList(); arrayList.add("张三"); arrayList.add("李四"); arrayList.add("王五"); System.out.println(arrayList.size()); arrayList.remove("张三"); System.out.println(arrayList.size()); Collection other = new ArrayList(); other.add("王五"); other.add("赵六"); arrayList.removeAll(other); System.out.println(arrayList.size()); } }
|
clear(): 清除所有元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package com.itguigu.collection;
import java.util.ArrayList; import java.util.Collection;
import org.junit.Test;
public class TestConlection { @Test public void test1() { Collection arrayList = new ArrayList(); arrayList.add("张三"); arrayList.add("李四"); arrayList.add("王五"); arrayList.clear(); System.out.println(arrayList.size()); } }
|
3. 修改
Collection 根接口中没有提供修改的方法,子接口中可能有
4. 查询
contains(object obj): 判断 obj 是否在当前集合中
containsAll(Collection c): 判断 c 中的元素是否都在当前集合中
isEmpty(): 判断是否为空
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package com.itguigu.collection;
import java.util.ArrayList; import java.util.Collection;
import org.junit.Test;
public class TestConlection { @Test public void test1() { Collection arrayList = new ArrayList(); arrayList.add("张三"); arrayList.add("李四"); arrayList.add("王五"); Collection other = new ArrayList(); other.add("张三"); other.add("田七"); System.out.println(arrayList.contains("张三")); System.out.println(arrayList.contains(other)); } }
|
Collection 根接口中没有提供获取一个元素的方法。
5. 遍历
toArray: 如果该集合的底层是数组实现,那么效率较高,否则则较低。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.itguigu.collection;
import java.util.ArrayList; import java.util.Collection;
import org.junit.Test;
public class TestConlection { @Test public void test1() { Collection arrayList = new ArrayList(); arrayList.add("张三"); arrayList.add("李四"); Object[] array = arrayList.toArray(); for (int i = 0; i < array.length; i++) { System.out.println(array[i]); } } }
|
foreach:可以称为增强版的 for 循环。如果只是查看数组或集合的元素,那么用 foreach 比较简单,如果涉及删除,修改,那么就不使用。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.itguigu.collection;
import java.util.ArrayList; import java.util.Collection;
import org.junit.Test;
public class TestConlection { @Test public void test1() { Collection arrayList = new ArrayList(); arrayList.add("张三"); arrayList.add("李四"); arrayList.add("王五"); for (Object object : arrayList) { System.out.println(object); } } }
|
Iterator: 迭代器。在 java.util.Iterator。用于遍历和循环集合使用。只支持遍历 Collection 集合,不支持数组。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package com.itguigu.collection;
import java.util.ArrayList; import java.util.Collection; import java.util.Iterator;
import org.junit.Test;
public class TestConlection { @Test public void test1() { Collection arrayList = new ArrayList(); arrayList.add("张三"); arrayList.add("李四"); arrayList.add("王五"); Iterator iterator = arrayList.iterator(); while (iterator.hasNext()) { Object object = (Object) iterator.next(); System.out.println(object); } } }
|
6. 其他
retainAll(Collection c):获取两个集合的交集
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package com.itguigu.collection;
import java.util.ArrayList; import java.util.Collection;
import org.junit.Test;
public class TestConlection { @Test public void test1() { Collection arrayList = new ArrayList(); arrayList.add("张三"); arrayList.add("李四"); arrayList.add("王五"); Collection other = new ArrayList(); other.add("张三"); other.add("田七"); arrayList.retainAll(other); System.out.println(arrayList.size()); } }
|
List
列表:可重复的,按顺序存储。也是接口,位置是 java.util.List
实现类:ArrayList(动态数组)
特点:
有序。可以使用索引精确的控制
可重复
常用方法:
因为是 Collection 的子接口,所有 Collection 有的方法,它都有。除此之外,还有很多和索引相关的方法。
add(index, Element): 在指定的 index 位置插入元素
addAll(index, Collection): 在指定的 index 位置插入多个元素。
remove(index): 删除指定位置的元素
set(index, Element): 修改指定位置的元素。collection 中是没有提供修改的方法的。
indexOf(object): 查询元素在集合中的位置,返回索引
lastindexOf(object): 查询元素在集合中的最后一个位置,返回索引
get(index): 返回 index 位置的元素
subList(fromIndex, toIndex): 截取,范围是 [fromIndex, toIndex)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| package com.itguigu.collection;
import java.util.ArrayList; import java.util.List;
import org.junit.Test;
public class TestConlection { @Test public void test1() { List list = new ArrayList(); list.add("张三"); list.add(0, "李四"); List other = new ArrayList(); other.add("王五"); other.add("赵六"); other.add(0, "李四"); list.addAll(0, other); list.remove(0); list.set(0, "吴十"); System.out.println(list.get(0)); System.out.println(list.indexOf("吴十")); System.out.println(list.lastIndexOf("李四")); for (Object object : list) { System.out.println(object); } } }
|
collection 中遍历集合中的元素有三种方法,分别是 for,foreach 和 Iterator。在 List 中还可以使用 ListIterator,它是 Iterator 的子接口,拥有 Iterator 的所有方法。除此之外遍历还可以指定方向,指定位置,还新增了 add 方法,set 方法等。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37
| package com.itguigu.collection;
import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator;
import org.junit.Test;
public class TestConlection { @Test public void test1() { List list = new ArrayList(); list.add("张三"); list.add(0, "李四"); list.add("王五"); list.add("赵六"); list.add(0, "李四"); ListIterator listIterator = list.listIterator(); while (listIterator.hasNext()) { Object object = (Object) listIterator.next(); System.out.println(object); } System.out.println("---------------------"); ListIterator listIterator2 = list.listIterator(list.size()); while (listIterator2.hasPrevious()) { Object object = (Object) listIterator2.previous(); System.out.println(object); } } }
|
常见实现类
Veactor: 动态数组,旧版本,线程安全的。内部实现为数组,初始化大小为 10。扩容时,扩容为原来的2倍。
ArrayList: 动态数组,新版本,线程安全的。内部实现为数组,初始化大小为 10。扩容时,扩容为原来的1.5倍。【使用频率较高】
LinkedList: 双向链表,双端队列。内部实现为链表。【使用频率较高】
Stack: 栈,Veactor 的子类。内部实现为数组。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| package com.itguigu.collection;
import java.util.LinkedList;
import org.junit.Test;
public class TestList { @Test public void test() { LinkedList linkedList = new LinkedList(); linkedList.offerFirst(1); linkedList.offerFirst(2); linkedList.offerLast(3); linkedList.offerLast(4); for (Object object : linkedList) { System.out.println(object); } } }
|
动态数组和 LinkedList 的区别是什么?
- 内部实现不同,动态数组底层为数组。LinkedList 底层为链表
- 动态数组对索引相关的操作效率很高,LinkedList 则较低
- 动态数组的插入,删除涉及到元素的移动,LinkedList 的删除,插入只涉及到前后元素的关系。
- 如果是操作索引更多,那么可以选择动态数组。如果是添加删除,插入等操作,那么就选择链表。
Set
集:不可重复的,无序的(和添加顺序无关)。位置为 java.util.Set,是 Collection 的子接口
特点:
- 元素不重复
- 无序的(和添加顺序无关)
常见方法:
因为是 Collection 的子接口,所有 Collection 有的方法,它都有。Set 没有自己新增方法。
常见实现类:
HashSet:完全无序。保证元素不重复是靠对象的 equals 方法。所以在使用 HashSet 的时候需要重写对象的 equals 方法。
TreeSet: 可以按照大小排序,和添加顺序无关。保证元素不重复是靠 Comparable 接口的 compareTo 方法,或者其他的比较方法,例如 java.util.Comparator。例如两个李四都是 36 岁,但是第一个李四成绩为 99 分,第二个为 88 分。假如 compareTo 方法实现的功能是比较年纪,所以就认为这两个对象是相同的,那么第二个李四就不会添加进入集合当中。
LinkedHashSet:遍历的时候可以保证顺序是添加时候的顺序,但是存储和添加顺序无关。LinkedHashSet 是 HashSet 的子类,但是要比 HashSet 多维护一个添加的顺序,所以效率比 HashSet 要低。保证元素不重复是靠对象的 equals 方法。所以在使用 HashSet 的时候需要重写对象的 equals 方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
| package com.itguigu.collection;
import java.util.Comparator; import java.util.HashSet; import java.util.LinkedHashSet; import java.util.TreeSet;
import org.junit.Test;
public class TestList { @SuppressWarnings("all") @Test public void test() { HashSet hashSet = new HashSet(); hashSet.add("张三"); hashSet.add("李四"); hashSet.add("王五"); hashSet.add("李四"); for (Object object : hashSet) { System.out.println(object); } System.out.println("-------------------"); } @SuppressWarnings("all") @Test public void test2() { TreeSet treeSet = new TreeSet(); treeSet.add(new Student("张三", 99, 20)); treeSet.add(new Student("李四", 80, 33)); treeSet.add(new Student("王五", 76, 19)); treeSet.add(new Student("李四", 80, 33)); for (Object object : treeSet) { System.out.println(object); } System.out.println("-------------------"); } @SuppressWarnings("all") @Test public void test3() { TreeSet treeSet = new TreeSet(new Comparator() { @Override public int compare(Object o1, Object o2) { Student student1 = (Student) o1; Student student2 = (Student) o2; return student1.getAge() - student2.getAge(); } }); treeSet.add(new Student("张三", 99, 20)); treeSet.add(new Student("李四", 80, 33)); treeSet.add(new Student("王五", 76, 19)); treeSet.add(new Student("李四", 80, 33)); for (Object object : treeSet) { System.out.println(object); } System.out.println("-------------------"); } @SuppressWarnings("all") @Test public void test4() { LinkedHashSet linkedHashSet = new LinkedHashSet(); linkedHashSet.add(new Student("李四", 80, 33)); linkedHashSet.add(new Student("王五", 76, 19)); linkedHashSet.add(new Student("张三", 99, 20)); for (Object object : linkedHashSet) { System.out.println(object); } System.out.println("-------------------"); } }
class Student implements Comparable{ private String name; private int score; private int age; public Student(String name, int score, int age) { super(); this.name = name; this.score = score; this.age = age; } public Student() { super(); } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getScore() { return score; } public void setScore(int score) { this.score = score; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Student [name=" + name + ", score=" + score + ", age=" + age + "]"; } @Override public int compareTo(Object o) { Student student = (Student) o; return this.score - student.score; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + age; result = prime * result + ((name == null) ? 0 : name.hashCode()); result = prime * result + score; 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 (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; if (score != other.score) return false; return true; } }
|
结论:
- 如果既要元素不重复,又要可以支持大小排序,那么使用 TreeSet
- 如果既要元素不重复,又要保证添加顺序,那么可以使用 LinkedHashSet
- 如果只是需要元素不重复,那么 HashSet 既可。
Map
Java.util.Map接口与Collection 最大的不同就是 Map 存储的为 键值对。
Map常用方法
1. 添加:
put(key, value)
putAll(Map map)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package com.itguigu.Map;
import java.io.BufferedWriter; import java.util.HashMap;
public class TestMap { @SuppressWarnings("all") public static void main(String[] args) { HashMap hashMap = new HashMap(); hashMap.put("key", "value"); hashMap.put("key1", null); hashMap.put("key2", new String[] {"value1", "value2"}); HashMap hashMap2 = new HashMap(); hashMap2.put("key3", "value3"); hashMap2.put("key4", "value4"); hashMap.putAll(hashMap2); System.out.println(hashMap.size()); } }
|
2. 删除:
remove(Object Key): 根据 key 删除
clear(): 清空
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| package com.itguigu.Map;
import java.util.HashMap;
public class TestMap { @SuppressWarnings("all") public static void main(String[] args) { HashMap hashMap = new HashMap(); hashMap.put("key", "value"); hashMap.put("key1", null); hashMap.put("key2", new String[] {"value1", "value2"}); hashMap.remove("key"); System.out.println(hashMap.size()); hashMap.clear(); System.out.println(hashMap.size()); } }
|
3.修改:
通过 put 可以替换 value
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| package com.itguigu.Map;
import java.util.HashMap;
public class TestMap { @SuppressWarnings("all") public static void main(String[] args) { HashMap hashMap = new HashMap(); hashMap.put("key", "value"); hashMap.put("key", "new value"); } }
|
4. 查询:
containsKey(Object key): 判断 key 是否存在
containsValue(Object value): 判断 value 是否存在
get(Object key): 根据 key 获取 value
isEmpty(): 判断是否为空
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package com.itguigu.Map;
import java.util.HashMap;
public class TestMap { @SuppressWarnings("all") public static void main(String[] args) { HashMap hashMap = new HashMap(); hashMap.put("key", "value"); hashMap.put("key2", "value2"); hashMap.put("key3", "value3"); System.out.println(hashMap.containsKey("key3")); System.out.println(hashMap.containsValue("value2")); System.out.println(hashMap.isEmpty()); System.out.println(hashMap.get("key")); } }
|
5. 遍历:
keySet:获取 map 中的所有key,因为 key 不能重复,所以是一个 set。
values: 获取 map 的值。因为值可能是重复的,所以 values 返回的是 collection 类型。
entrySet:返回由 entry 对象构成的 set,因为 key 不会重复,所以 entry 对象也不会重复
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| package com.itguigu.Map;
import java.util.Collection; import java.util.HashMap; import java.util.Set;
public class TestMap { @SuppressWarnings("all") public static void main(String[] args) { HashMap hashMap = new HashMap(); hashMap.put("key", "value"); hashMap.put("key2", "value2"); hashMap.put("key3", "value3"); Set keySet = hashMap.keySet(); for (Object object : keySet) { System.out.println(object); } Collection values = hashMap.values(); for (Object object : values) { System.out.println(object); } Set entrySet = hashMap.entrySet(); for (Object object : entrySet) { System.out.println(object); } } }
|
常见实现类
HashMap
Hashtable
LinkedHashMap:是 HashMap 的子类,比 HashMap 多维护了添加的顺序,也就是说添加是什么顺序,遍历就是什么顺序。
TreeMap:可根据 key 进行排序。所以key必须支持排序,即实现,java.lang.Comparable 接口,或者单独为 TreeMap 定制比较器。
Properties:是 hashtable 的子类,键和值都是字符串。
HashMap 和 Hashtable 的区别:Hashtable 是旧版本的,线程安全的,HashMap 是比 Hashtable 新的,是线程不安全的。Hashtable 的 key 和 value 都不允许为 null。HashMap 的 key 和 value 都允许为 null。