Java_03 集合:Collection,List,ArrayList,LinkedList,HashSet,TreeSet,Map,HashMap
目录
集合
-
定义:集合表示一组被称为其元素的对象。一些集合允许重复元素,一些集合不允许;对象的容器,实现了对对象常用的操作,类似数组功能
-
和数组区别:
- 数组长度固定,集合长度不固定
- 数组可以存储基本类型和引用类型,集合只能存引用类型
Collection
继承结构:
-
ArrayList/LinkedList/Vector > List > Collection
-
TreeSet > SortedSet > Set > Collection
-
HashSet > Set > Collection
package com.alpari;
import java.util.ArrayList;
import java.util.Collection;
public class DemoCollection {
public static void main(String[] args) {
// 创建集合
Collection collection = new ArrayList();
// 添加元素
collection.add("java");
collection.add("c++");
System.out.println("元素个数 "+collection.size()); // 打印:元素个数 2
// 删除
// collection.remove("c++");
// collection.clear();
// 遍历
// 1.增强for循环
for (Object o : collection) {
System.out.println(o);
}
// 2.使用迭代器iterator
// hasNext();有没有下一个元素 next();获取下一个元素 remove();删除元素
Iterator it = collection.iterator();
while (it.hasNext()) {
String s = (String)it.next();
System.out.println(s);
//collection.remove(s); // 不可以用这种删除
it.remove(); // 只能这种删除
}
}
}
List
有序,元素可重复
package com.alpari;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class DemoList {
public static void main(String[] args) {
List list = new ArrayList();
// add
list.add("java");
list.add(0,"c++");
System.out.println(list.toString()); //[c++, java]
// remove
//list.remove("java"); //按对象删除
//list.remove(0); // 按下标删除
// 遍历 1
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
// 增强for 2
for (Object o:list) {
System.out.println(o);
}
// 使用iterator迭代器 3
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// 使用listIterator 4
ListIterator iterator = list.listIterator();
// 从前到后输出
while (iterator.hasNext()) {
System.out.println(iterator.nextIndex()+" : "+iterator.next());
}
// 从后往前输出
while (iterator.hasPrevious()) {
System.out.println(iterator.previousIndex()+" : "+iterator.previous());
}
// 判断
System.out.println(list.contains("java")); // true
System.out.println(list.isEmpty()); // false
// 获取位置
System.out.println(list.indexOf("java")); // 1
}
}
ArrayList
package com.alpari;
import java.util.ArrayList;
/**
* JDK1.2
* 有序集合,元素可重复,线程不安全
* 存储结构:数组,查找快,增删慢
* 初始化为空数组,添加第一个元素变为10:DEFAULT_CAPACITY = 10,之后扩容为原来的1.5倍
* 源码中elementData 存放数据的数组
*/
public class DemoArrayList {
public static void main(String[] args) {
ArrayList<Object> list = new ArrayList<>();
list.add("w");
list.add("e");
list.add("w");
list.add("w");
list.add("r");
// 删除重复元素,需要倒叙删除
for (int i = list.size()-1; i >= 0; i--) {
if ("w".equals(list.get(i))) {
list.remove("w");
}
}
System.out.println(list.toString());
// 遍历省略,和list基本一样。
}
}
// 源码add方法扩容 刚创建对象时 size=0,容量=0
public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}
private void ensureCapacityInternal(int minCapacity) {
if (elementData == DEFAULTCAPACITY_EMPTY_ELEMENTDATA) {
minCapacity = Math.max(DEFAULT_CAPACITY, minCapacity);
}
ensureExplicitCapacity(minCapacity);
}
private void ensureExplicitCapacity(int minCapacity) {
modCount++;
// overflow-conscious code
if (minCapacity - elementData.length > 0)
grow(minCapacity);
}
private void grow(int minCapacity) {
// overflow-conscious code
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1);
if (newCapacity - minCapacity < 0)
newCapacity = minCapacity;
if (newCapacity - MAX_ARRAY_SIZE > 0)
newCapacity = hugeCapacity(minCapacity);
// minCapacity is usually close to size, so this is a win:
elementData = Arrays.copyOf(elementData, newCapacity);
}
LinkedList
package com.alpari;
import java.util.LinkedList;
/**
* JDK1.2
* 基于双向链表,线程不安全,查询慢,增删快
*/
public class DemoLinkedList {
public static void main(String[] args) {
LinkedList list = new LinkedList();
// 操作和ArrayList基本一样
}
}
Vector
package com.alpari;
import java.util.Enumeration;
import java.util.Vector;
/**
* JDK1.0
* 基于数组实现,线程安全,效率低被替代
*/
public class DemoVector {
public static void main(String[] args) {
Vector<Object> vector = new Vector<>();
vector.add("java");
// 使用枚举遍历
Enumeration en = vector.elements();
while (en.hasMoreElements()) {
System.out.println(en.nextElement());
}
}
}
set
package com.alpari;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* 无序,不能重复
*/
public class DemoSet {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
// add
set.add("java");
set.add("c++");
// set.add("java");
// del
// set.remove("c++");
// 遍历
for (String s : set) {
System.out.println(s);
}
Iterator iterator = set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// 判断 contains isEmpty
}
}
HashSet
package com.alpari;
import java.util.HashSet;
import java.util.Iterator;
/**
* 基于hashMap实现,用了其key保存数据,无序,可以存null,值不可以重复,不安全
* 存储结构:哈希表(数组+链表+红黑树)
* 存储过程:1.根据hashcode计算保存的位置,如果此位置为空,则直接保存,否则执行第二步
* 2.再执行equals方法,如果equals为true,则认为重复,否则形成链表,添加元素
* 即添加元素需要对比其hashcode与equals,如果自定义引用数据类型,需要重写hashcode与equals方法
*/
public class DemoHashSet {
public static void main(String[] args) {
HashSet<String> hashSet = new HashSet<>();
//add
hashSet.add("java");
hashSet.add("c++");
// hashSet.add("java"); 添加不了
// del
// hashSet.remove("java");
// 遍历
for (String s: hashSet) {
System.out.println(s);
}
Iterator<String> iterator = hashSet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
// contains判断是否有了;isEmpty判断是否为空
}
}
TreeSet
package com.alpari;
import java.util.TreeSet;
/**
* 元素不可重复,自动排序,不存null,不安全
* 红黑树
* 自定义引用数据类型需要实现Comparable接口,重写compareTo()方法,定义比较规则,返回值为0,认为是重复元素
* Comparator 接口实现定制比较
*/
public class DemoTreeSet {
public static void main(String[] args) {
TreeSet<String> treeSet = new TreeSet<>();
// add
treeSet.add("java");
treeSet.add("c++");
// treeSet.add("c++"); // 元素重复,不添加
// del
// treeSet.remove("c++");
// contains isEmpty ...
}
}
Map
package com.alpari;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
/**
* key-value键值对,不安全,可以存null
* key:无序,无下标,不可重复
* value:可重复
*/
public class DemoMap {
public static void main(String[] args) {
HashMap<String, String> map = new HashMap<>();
// add
map.put("q","java");
map.put("w","c++");
map.put("w","c"); // key重复,会把c++取代
System.out.println(map.toString()); // {q=java, w=c}
// 遍历
// 使用keySet,返回值是set集合,可以用迭代器或增强for遍历
// Set<String> set = map.keySet();
for (String key: map.keySet()) {
System.out.println(key+" : "+map.get(key));
}
// 使用entrySet,返回的是Map.Entry映射对,里面是key-value,效率高于keySet
// Set<Map.Entry<String, String>> entries = map.entrySet();
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry.getKey()+" : "+entry.getValue());
}
// 判断
// map.containsKey("q"); // map.containsValue("java");
}
}
HashMap
package com.alpari;
import java.util.HashMap;
import java.util.Map;
/**
* JDK1.2
* 可以为null,线程不安全
* 存储结构:哈希表;使用hashcode与equals方法来对比元素是否重复
* 添加第一个元素容量为16,当元素个数超过阈值时,即16*0.75时,扩容为2n
* JDK1.8当每个链表长度大于8,且数组元素个数>=64时,会调整为红黑树;当链表长度<6,调整成链表;1.8之前链表时头插入,1.8之后是尾插入
*/
public class DemoHashMap {
public static void main(String[] args) {
HashMap<Integer, String> hashMap = new HashMap<>();
// 添加 用put
hashMap.put(1, "java");
hashMap.put(2, "c++");
hashMap.put(3, "c");
System.out.println(hashMap.toString()); // {1=java, 2=c++, 3=c}
// 删除用 remove
// 遍历
// 使用keySet
for (Integer key:hashMap.keySet()) {
System.out.println(key+" : "+hashMap.get(key));
}
// 使用entrySet
for (Map.Entry<Integer, String> m: hashMap.entrySet()) {
System.out.println(m.getKey()+":"+m.getValue());
}
}
}
HashTable
package com.alpari;
/**
* JDK1.0
* 不能为null,线程安全,初始容量11,扩容2n+1
*/
public class DemoHashTable {
}
TreeMap
package com.alpari;
/**
* 类似于TreeSet的使用,添加元素用put(key, value);
*/
public class DemoTreeMap {
}
Collections
集合的工具类,里面封装了一些操作集合的方法,如:Conllection.reverse()反转,Conllection.shuffle打乱等
补充数组集合转换
package com.alpari;
import java.util.Arrays;
import java.util.List;
public class Demo {
public static void main(String[] args) {
// 数组转为集合,基本类型的数组转换成集合时,要用其包装类
String[] name = {"q","w","e","r"};
List<String> list = Arrays.asList(name);
System.out.println(list);
// 集合转为数组
String[] arr = list.toArray(new String[5]);
System.out.println(Arrays.toString(arr));
}
}
// 输出:
[q, w, e, r]
[q, w, e, r, null]