写在前面
集合部分的内容实在太多了,本篇博客主要是对本章内容的总结回顾,对于ArrayList、HashMap的底层源码后面会专门找个时间重新写~
概述
本章内容主要学习:Collection接口,及其两个子接口List、Set的实现子类,Iterator迭代器接口;Map接口及其实现子类。其中List的实现子类有ArrayList、LinkedList、Vector等,Set的实现子类有HashSet、LinkedHashSet、TreeSet等;Map的实现子类有HashMap、LinkedHashMap、TreeMap、Hashtable、Properties等,下面是两大接口的继承树:
Collection:
Map:
两种体系的对比:
Collection接口
概述
1.Collection 接口是 List、Set 和 Queue 接口的父接口,该接口里定义的方法既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合。
2.JDK不提供此接口的任何直接实现,而是提供更具体的子接口(如:Set和List)实现。
3.在 Java5 之前,Java 集合会丢失容器中所有对象的数据类型,把所有对象都当成 Object 类型处理;从 JDK 5.0 增加了泛型以后,Java 集合可以记住容器中对象的数据类型。
Collection接口常用方法
part1
1.boolean add(Object obj):添加一个元素
2.boolean addAll(Collection coll):增加一个集合
3.int size():返回一个集合的有效元素个数
4.void clear():清空集合的元素
5.boolean isEmpty():判断是否为空集合
demo01:
package com.deserts;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
/**
* 测试Collextion接口方法1:
* boolean add(Object obj):添加一个元素
* boolean addAll(Collection coll):增加一个集合
* int size():返回一个集合的有效元素个数
* void clear():清空集合的元素
* boolean isEmpty():判断是否为空集合
*/
public class Demo01 {
public static void main(String[] args) {
Collection coll = new ArrayList();
//add(Object obj):添加一个元素
coll.add(123);//自动装箱
coll.add("deserts");
coll.add(new Date());
coll.add(3.1415926);
System.out.println(coll);
Collection coll1 = new ArrayList();
coll1.add(456);
coll1.add("xuan");
//addAll(Collection coll):增加一个集合
coll.addAll(coll1);
System.out.println(coll);
//int size():返回一个集合的有效元素个数
System.out.println("coll.size: " + coll.size());
//void clear():清空集合的元素
coll.clear();
//boolean isEmpty():判断是否为空集合
System.out.println(coll.isEmpty());
}
}
part2
1.boolean contains(Object obj):是通过元素的equals方法来判断是否是同一个对象
2.boolean containsAll(Collection c):也是调用元素的equals方法来比较的。 拿两个集合的元素挨个比较。
3. boolean remove(Object obj) :通过元素的equals方法判断是否是要删除的那个元素。 只会删除找到的第一个元素
4. boolean removeAll(Collection coll):取当前集合的差集
demo02:
package com.deserts;
import java.util.ArrayList;
import java.util.Collection;
/**
* 测试Collextion接口方法2:
* boolean contains(Object obj):是通过元素的equals方法来判断是否是同一个对象
* boolean containsAll(Collection c):也是调用元素的equals方法来比较的。
* 拿两个集合的元素挨个比较。
* boolean remove(Object obj) :通过元素的equals方法判断是否是要删除的那个元素。
* 只会删除找到的第一个元素
* boolean removeAll(Collection coll):取当前集合的差集
*
*/
public class Demo02 {
public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add(123);//自动装箱
coll.add("deserts");
coll.add(false);
coll.add(3.1415926);
//boolean contains(Object obj):是通过元素的equals方法来判断是否是同一个对象
System.out.println("coll is contain 123: " + coll.contains(123));
Collection coll1 = new ArrayList();
coll1.add(123);//自动装箱
coll1.add("deserts");
//boolean containsAll(Collection c):也是调用元素的equals方法来比较的。拿两个集合的元素挨个比较。
System.out.println("coll is contain coll1: " + coll.containsAll(coll1));
//boolean remove(Object obj) :通过元素的equals方法判断是否是要删除的那个元素。
System.out.println("是否移除3.1415926成功: " + coll.remove(3.1415926));
System.out.println(coll);
//boolean remove(Object obj) :通过元素的equals方法判断是否是要删除的那个元素。只会删除找到的第一个元素
System.out.println("coll、coll1求差集: " + coll.removeAll(coll1));
System.out.println(coll);
}
}
part3
1.boolean retainAll(Collection c):把交集的结果存在当前集合中,不影响c
2.boolean equals(Object obj):集合是否相等
3.Object[] toArray():转成对象数组
4.int hashCode():获取集合对象的哈希值
5.Iterator iterator():返回迭代器对象,用于集合遍历
demo03:
package com.deserts;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
/**
* 测试Collextion接口方法3:
* boolean retainAll(Collection c):把交集的结果存在当前集合中,不影响c
* boolean equals(Object obj):集合是否相等
* Object[] toArray():转成对象数组
* int hashCode():获取集合对象的哈希值
* Iterator iterator():返回迭代器对象,用于集合遍历
*/
public class Demo03 {
public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add(123);
coll.add("deserts");
coll.add(false);
coll.add(3.1415926);
Collection coll1 = new ArrayList();
coll1.add(123);
coll1.add("deserts");
coll1.add(false);
//boolean retainAll(Collection c):把交集的结果存在当前集合中,不影响c
coll.retainAll(coll1);
System.out.println(coll);
//boolean equals(Object obj):集合是否相等
System.out.println(coll.equals(coll1));
System.out.println("$$$$$$$$$$$$$$$$$$$");
//Object[] toArray():转成对象数组
Object[] obj = coll.toArray();
System.out.println(Arrays.toString(obj));
//int hashCode():获取集合对象的哈希值
System.out.println(coll.hashCode());
System.out.println("*******************");
//Iterator iterator():返回迭代器对象,用于集合遍历
Iterator it = coll.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
Iterator迭代器接口
概述
1.Iterator对象称为迭代器(设计模式的一种),主要用于遍历 Collection 集合中的元素。
2.Iterator 仅用于遍历集合,Iterator 本身并不提供承装对象的能力。如果需要创建Iterator 对象,则必须有一个被迭代的集合。
3.集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。
常用方法
Iterator接口作为迭代器主要功能是遍历,用于遍历的两个方法是:boolean hasNext(); E next();除此之外,还提供了remove()方法
原理:
除了使用Iterator接口,还可使用for each循环(增强for循环)进行遍历
demo:
package com.deserts;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* 测试两种遍历方式
*/
public class demo04 {
public static void main(String[] args) {
Collection coll = new ArrayList();
coll.add(123);
coll.add("deserts");
coll.add(false);
coll.add(3.1415926);
//Iterator迭代器输出
Iterator it = coll.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
System.out.println("*********************");
//for each输出
for(Object obj: coll){
System.out.println(obj);
}
}
}
List接口
概述
List接口是Collection子接口之一,是在JDK1.2新增的,它的子类ArrayList、LinkedList也是在JDK1.2新增的,同时JDK1.0就有的Vector也是它的子类
List接口方法
1.void add(int index, Object ele):在index位置插入ele元素
2. boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来
3.Object get(int index):获取指定index位置的元素
4.int indexOf(Object obj):返回obj在集合中首次出现的位置
5. int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
6.Object remove(int index):移除指定index位置的元素,并返回此元素
7. Object set(int index, Object ele):设置指定index位置的元素为ele
8. List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex位置的子集合
demo
package com.desertss.demo;
import java.util.ArrayList;
/**
* 测试List接口方法:
* void add(int index, Object ele):在index位置插入ele元素
* boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来
* Object get(int index):获取指定index位置的元素
* int indexOf(Object obj):返回obj在集合中首次出现的位置
* int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
* Object remove(int index):移除指定index位置的元素,并返回此元素
* Object set(int index, Object ele):设置指定index位置的元素为ele
* List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex位置的子集合
*
*/
public class Demo01 {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(123);
list.add(456);
list.add(true);
list.add(123);
list.add("deserts");
//void add(int index, Object ele):在index位置插入ele元素
list.add(2,"MM");
System.out.println(list);
ArrayList list1 = new ArrayList();
list1.add("xuan");
list1.add(false);
//boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来
System.out.println(list.addAll(1,list1));
System.out.println(list);
//Object get(int index):获取指定index位置的元素
System.out.println(list.get(4));
//int indexOf(Object obj):返回obj在集合中首次出现的位置
System.out.println(list.indexOf(123));
//int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
System.out.println(list.lastIndexOf(123));
//Object remove(int index):移除指定index位置的元素,并返回此元素
System.out.println(list.remove(4));
System.out.println(list);
//Object set(int index, Object ele):设置指定index位置的元素为ele
list.set(0,789);
System.out.println(list.get(0));
//List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex位置的子集合
Object list2 = list.subList(2,5);
System.out.println(list2);
}
}
ArrayList
概述
1.ArrayList 是 List 接口的典型实现类、主要实现类
2.本质上,ArrayList是对象引用的一个”变长”数组
底层
1.jdk 7情况下: ArrayList list = new ArrayList(); //底层创建了长度是10的Object[]数组elementData list.add(123);//elementData[0] = new Integer(123); ist.add(11);//如果此次的添加导致底层elementData数组容量不够,则扩容。
默认情况下,扩容为原来的容量的1.5倍,同时需要将原有数组中的数据复制到新的数组中。 结论:建议开发中使用带参的构造器:ArrayList list = new ArrayList(int capacity)2.jdk 8中ArrayList的变化: ArrayList list = new ArrayList();//底层Object[] elementData初始化为.并没有创建长度为10的数组
list.add(123);//第一次调用add()时,底层才创建了长度10的数组,并将数据123添加到elementData[0],后续的添加和扩容操作与jdk7 无异。
3.jdk7中的ArrayList的对象的创建类似于单例的饿汉式,而jdk8中的ArrayList的对象 的创建类似于单例的懒汉式,延迟了数组的创建,节省内存。
LinkedList
概述
对于频繁的插入或删除元素的操作,建议使用LinkedList类,效率较高
新增方法
底层
LinkedList底层的核心是一个内部类Node,这个类声明了属性item、next、prev分别来表示存储内容、链表头、链表尾,链表头记录下一个元素的位置,链表尾记录前一个元素的位置。
Vector
概述
1.Vector 是一个古老的集合,JDK1.0就有了。大多数操作与ArrayList相同,区别之处在于Vector是线程安全的。
2.在各种list中,最好把ArrayList作为缺省选择。当插入、删除频繁时,使用LinkedList;Vector总是比ArrayList慢,所以尽量避免使用。
新增方法
关于三者的异同
Set接口
概述
1.Set接口是Collection的子接口,set接口没有提供额外的方法
2.Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个Set 集合中,则添加操作失败。
3.Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals() 方法
HashSet
概述
向HashSet中添加元素的过程
1.当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法来得到该对象的 hashCode 值,然后根据 hashCode 值,通过某种散列函数决定该对象在 HashSet 底层数组中的存储位置。(这个散列函数会与底层数组的长度相计算得到在数组中的下标,并且这种散列函数计算还尽可能保证能均匀存储元素,越是散列分布,该散列函数设计的越好)
2.如果两个元素的hashCode()值相等,会再继续调用equals方法,如果equals方法结果为true,添加失败;如果为false,那么会保存该元素,但是该数组的位置已经有元素了,那么会通过链表的方式继续链接。
3.如果两个元素的 equals() 方法返回 true,但它们的 hashCode() 返回值不相等,hashSet 将会把它们存储在不同的位置,但依然可以添加成功。
重写hashCode()的原则
1.在程序运行时,同一个对象多次调用 hashCode() 方法应该返回相同的值。
2.当两个对象的 equals() 方法比较返回 true 时,这两个对象的 hashCode() 方法的返回值也应相等。
3.对象中用作 equals() 方法比较的 Field,都应该用来计算 hashCode 值。
重写equals()原则
LinkedHashSet
LinkedHashSet用的比较少,下列是简单介绍:
TreeSet
TreeSet主要是排序用,掌握了Java比较器就问题不大。需要注意的是,添加元素时不再使用haseCode()、equals()来比较,这时需要用到我们的java比较器。
自然排序
定制排序
代码示例:
package com.desertss.demo;
import java.util.Comparator;
import java.util.Iterator;
import java.util.Objects;
import java.util.TreeSet;
public class Demo05 {
public static void main(String[] args) {
//定制排序:先按价格从大到小排序,再按名字从小到大排序
Comparator comparator = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Goods && o2 instanceof Goods){
Goods g1 = (Goods)o1;
Goods g2 = (Goods)o2;
int com = -Double.compare(g1.getPrice(),g2.getPrice());
if (com == 0){
return g1.getName().compareTo(g2.getName());
}else {
return com;
}
}
throw new RuntimeException("类型不匹配");
}
};
TreeSet set = new TreeSet(comparator);
set.add(new Goods("辣条",3.5));
set.add(new Goods("快乐水",2.5));
set.add(new Goods("薯片",4));
set.add(new Goods("雪糕",5.5));
set.add(new Goods("酸奶",6.5));
Iterator it = set.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
}
}
class Goods implements Comparable{
private String Name;
private double price;
public Goods(String name, double price) {
Name = name;
this.price = price;
}
public String getName() {
return Name;
}
public double getPrice() {
return price;
}
@Override
public String toString() {
return "Goods{" +
"Name='" + Name + '\'' +
", price=" + price +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Goods goods = (Goods) o;
return Double.compare(goods.price, price) == 0 &&
Objects.equals(Name, goods.Name);
}
@Override
public int hashCode() {
return Objects.hash(Name, price);
}
//自然排序,先按名字再按价格排序
@Override
public int compareTo(Object o) {
if(o instanceof Goods){
Goods g = (Goods)o;
int compare = this.Name.compareTo(g.Name);
if(compare == 0){
return Double.compare(this.price,g.price);
}else {
return compare;
}
}
throw new RuntimeException("输入类型不匹配");
}
}
Map接口
概述
常用方法
添加、删除、修改操作:
- Object put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中
- .void putAll(Map m):将m中的所有key-value对存放到当前map中
- Object remove(Object key):移除指定key的key-value对,并返回value
- void clear():清空当前map中的所有数据
demo:
package com.deserts.demo;
import java.util.HashMap;
import java.util.Map;
/**
* 添加、删除、修改操作:
* Object put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中
* void putAll(Map m):将m中的所有key-value对存放到当前map中 Object remove(Object key):移除指定key的key-value对,并返回value
* void clear():清空当前map中的所有数据
*
*/
public class Demo01 {
public static void main(String[] args) {
Map map = new HashMap();
//Object put(Object key,Object value)
map.put("xiaoming",95);
map.put("lihua",59);
map.put("zhangsan",82);
map.put("lisi",74);
map.put("wangwu",100);
System.out.println(map);
Map map1 = new HashMap();
map1.put("bajie",44);
map1.put("wukong",64);
map1.put("laosha",76);
//void putAll(Map m)
map.putAll(map1);
System.out.println(map);
//void clear():清空当前map中的所有数据
map.clear();
System.out.println(map.isEmpty());
}
}
元素查询的操作:
- Object get(Object key):获取指定key对应的value
- boolean containsKey(Object key):是否包含指定的key
- boolean containsValue(Object value):是否包含指定的value
- int size():返回map中key-value对的个数
- boolean isEmpty():判断当前map是否为空
- boolean equals(Object obj):判断当前map和参数对象obj是否相等
demo:
package com.deserts.demo;
import java.util.HashMap;
import java.util.Map;
/**
* 元素查询的操作:
* Object get(Object key):获取指定key对应的value
* boolean containsKey(Object key):是否包含指定的key
* boolean containsValue(Object value):是否包含指定的value
* int size():返回map中key-value对的个数
* boolean isEmpty():判断当前map是否为空
* boolean equals(Object obj):判断当前map和参数对象obj是否相等
*/
public class Demo02 {
public static void main(String[] args) {
Map map = new HashMap();
map.put("xiaoming",95);
map.put("lihua",59);
map.put("zhangsan",82);
map.put("lisi",74);
map.put("wangwu",100);
//Object get(Object key):获取指定key对应的value
System.out.println(map.get("lihua"));
//boolean containsKey(Object key):是否包含指定的key
System.out.println(map.containsKey("zhangsan"));
//boolean containsValue(Object value):是否包含指定的value
System.out.println(map.containsValue(95));
//int size():返回map中key-value对的个数
System.out.println(map.size());
//boolean equals(Object obj):判断当前map和参数对象obj是否相等
System.out.println(map.equals("zhangsan"));
}
}
元视图操作的方法:
- Set keySet():返回所有key构成的Set集合
- Collection values():返回所有value构成的Collection集合
- Set entrySet():返回所有key-value对构成的Set集合
demo:
package com.deserts.demo;
import java.util.*;
/**
* 元视图操作的方法:
* Set keySet():返回所有key构成的Set集合
* Collection values():返回所有value构成的Collection集合
* Set entrySet():返回所有key-value对构成的Set集合
*/
public class Demo03 {
public static void main(String[] args) {
Map map = new HashMap();
map.put("xiaoming",95);
map.put("lihua",59);
map.put("zhangsan",82);
map.put("lisi",74);
map.put("wangwu",100);
//Set keySet():返回所有key构成的Set集合
Set set = map.keySet();
Iterator it = set.iterator();
while (it.hasNext()){
System.out.println(it.next());
}
System.out.println();
//Collection values():返回所有value构成的Collection集合
Collection values = map.values();
for(Object obj: values){
System.out.println(obj);
}
System.out.println();
//Set entrySet():返回所有key-value对构成的Set集合
Set set1 = map.entrySet();
Iterator it1 = set1.iterator();
while (it1.hasNext()){
Map.Entry entry = (Map.Entry)it1.next();
System.out.println(entry.getKey() + "--->" + entry.getValue());
}
}
}
HashMap
概述
结构图:
底层
JDK8.0之前:
JDK8.0的变化:
有关源码分析,会在后面找时间写博客分析
LinkedHashMap
概况
TreeMap
概述
自然排序demo:
package com.deserts.demo;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
/**
* TreeMap自然排序测试
*/
public class Demo04 {
public static void main(String[] args) {
Student s1 = new Student("zhangsan", 85);
Student s2 = new Student("lisi", 95);
Student s3 = new Student("wangwu", 68);
Student s4 = new Student("lihua", 59);
Student s5 = new Student("xiaoming", 74);
TreeMap map = new TreeMap();
map.put(s1,18);
map.put(s2,20);
map.put(s3,19);
map.put(s4,18);
map.put(s5,19);
Set set = map.entrySet();
Iterator it = set.iterator();
while (it.hasNext()){
Map.Entry entry = (Map.Entry)it.next();
System.out.println(entry.getKey() + "--->" + entry.getValue());
}
}
}
class Student implements Comparable{
private String name;
private int score;
public Student(String name, int score) {
this.name = name;
this.score = score;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", score=" + score +
'}';
}
@Override
public int compareTo(Object o) {
if(o instanceof Student){
Student s = (Student)o;
return this.name.compareTo(s.name);
}
throw new RuntimeException("类型不匹配");
}
}
定制排序demo:
package com.deserts.demo;
import java.util.*;
/**
* Map定制排序测试
*/
public class Demo05 {
public static void main(String[] args) {
Student1 s1 = new Student1("zhangsan", 85);
Student1 s2 = new Student1("lisi", 95);
Student1 s3 = new Student1("wangwu", 68);
Student1 s4 = new Student1("lihua", 59);
Student1 s5 = new Student1("xiaoming", 74);
TreeMap map = new TreeMap(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if(o1 instanceof Student1 && o2 instanceof Student1) {
Student1 s1 = (Student1)o1;
Student1 s2 = (Student1)o2;
return -Integer.compare(s1.getScore(),s2.getScore());
}
throw new RuntimeException("类型不匹配");
}
});
map.put(s1,18);
map.put(s2,20);
map.put(s3,19);
map.put(s4,18);
map.put(s5,19);
Set set = map.entrySet();
Iterator it = set.iterator();
while (it.hasNext()){
Map.Entry entry = (Map.Entry)it.next();
System.out.println(entry.getKey() + "--->" + entry.getValue());
}
}
}
class Student1{
private String name;
private int score;
public Student1(String name, int score) {
this.name = name;
this.score = score;
}
public String getName() {
return name;
}
public int getScore() {
return score;
}
@Override
public String toString() {
return "Student1{" +
"name='" + name + '\'' +
", score=" + score +
'}';
}
}
Hashtable
Hashtable已经很少用了,下面是简介:
Properties
Properties主要用于处理属性文件
Collection工具类
Collections 是一个操作 Set、List 和 Map 等集合的工具类
排序方法:
查找、替换
同步控制
补充内容
写在最后
集合的内容真的是学这么久JavaSE以来内容最多最难的一章,还需要多花时间,可以是数据结构还没学写在源码不能看得特别清晰。下面就要进入泛型的学习了,冲冲冲!