目录
1.2 集合涉及的API(Collection 和Map两个接口)
05 Collection的子接口之二-------Set接口(无序 不可重复)
6.3.1 HashMap底层原理jdk7.0和JDK8.0底层原理实现
6.3.2 HashMap的子类: LinkedHashMap
01 集合框架概述
- 集合,数组都是对多个数据进行存储操作的结构,简称Java容器。此时的存储,主要指内存层面的存储,不涉及持久化存储(指保存在文件里)
- 数组在存储多个数据方面的特点:
- .数组一旦初始化长度就确定了
- 数组声明的类型,就决定了元素初始化的类型
- 比如: Object[] arr1;String[] arr;
- 数组在存储多个数据的缺点
- 一旦初始化后,数组长度不可修改,不便于扩展。
- 数组中提供的方法有限,对于数据的添加,删除,插入等操作非常不便
- 获取数组中实际元素个数,数组没有现成方法可用
- 数组存储数据特点有序,可以重复(删除一个数据,后面的数据就要往前提)
1.1 集合的使用场景
1.2 集合涉及的API(Collection 和Map两个接口)
1.2.1 Collection接口继承树
---Collection接口,单列集合,存储一个一个对象
* 1.List接口: 存储有序,可重复数据。(与数组类似,但可以修改长度)动态数组
* 主要实现类:ArrayList,LinkedList,Vector
*
* 2. Set接口: 存储无序的,不可重复的数据。(高中讲的集合:无序性,确定性,互异性)
* 主要实现类:HashSet,LinkedSet,TreeSet
1.2.2 Map继承树
--- Map接口, 双列结合,用来存储(Key-Value)数据(高中函数:y=f(x))
* 主要实现类:HashMap,LinkedHashMap,TreeMap,HashTable,Properties
02 Collection接口方法
- Collection 接口是List、Set 和Queue 接口的父接口,该接口里定义的方法既可用于操作Set 集合,也可用于操作List 和Queue 集合。
- JDK不提供此接口的任何直接实现,而是提供更具体的子接口(如:Set和List)实现。
- 在Java5 之前,Java 集合会丢失容器中所有对象的数据类型,把所有对象都当成Object 类型处理;从JDK 5.0 增加了泛型以后,Java 集合可以记住容器中对象的数据类型。
2.1 Collection接口常用方法
添加
- add(Object obj)
- addAll(Collection coll)
获取有效元素的个数
- int size()
清空集合
- void clear()
是否是空集合
boolean isEmpty()
public class CollectionTest {
@Test
public void test1(){
Collection collection = new ArrayList(); //向下转型
// add(Object e): 将元素e添加到集合collection中
collection.add("AA");
collection.add("BB");
collection.add("123");
collection.add(new Date());
// size(); 获取添加元素的个数
System.out.println(collection.size()); //4
// addAll(Collection c) //将其他集合c中的元素添加到当前集合中
Collection coll = new ArrayList(); //向下转型
coll.add(456);
coll.add("CC");
collection.addAll(coll);
System.out.println(collection.size()); //6
// isEmpty(): 判断当前集合是否为空
System.out.println(collection.isEmpty());//false
// clear(): 清空集合元素
coll.clear();
System.out.println(coll.isEmpty());//true
}
}
是否包含某个元素
- boolean contains(Object obj):是通过元素的equals方法来判断是否是同一个对象。
- boolean containsAll(Collection c):也是调用元素的equals方法来比较的。拿两个集合的元素挨个比较。
- 向Collection接口中实现类中添加对象时,要求对象重写了equals方法
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
public class Collectiontest1 {
@Test
public void Test1(){
Collection collection = new ArrayList();
collection.add(123);
collection.add(456);
collection.add(new String("Person"));
Person person = new Person("Terry",23);
collection.add(person);
// contains(Object o),返回布尔值,判断是否包含这个变量,在判断时会调用obj所在类的equals方法。向Collection接口中实现类中添加对象时,要求对象重写了equals方法
boolean contain = collection.contains(123); //true,String类中重写了equals方法
System.out.println(contain);
System.out.println(
collection.contains(new String("Person")));//true,调用String类中的equals判断
System.out.println(collection.contains(person)); //true
Person p = new Person("Tom",15);
collection.add(p);
System.out.println(collection.contains(new Person("Tom", 15)));// 这里返回false,因为Persin类中没有重写equels方法
// 2. containsAll
Collection coll = Arrays.asList(123,456);
System.out.println(collection.containsAll(coll)); //true,coll是collection的非空子集
}
删除
- boolean remove(Object obj) :通过元素的equals方法判断是否是要删除的那个元素。只会删除找到的第一个元素
- boolean removeAll(Collection coll):取当前集合的差集
@Test
// remove 和 removeAll
public void test2(){
// remove(object obj),通过元素obj的equals方法判断是否要删除呢个元素,只删除找到的第一个元素
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Person("Jerry",13));
coll.add(new String("Tom"));
coll.add(false);
coll.remove(123); // 有返回值,先判断有没有”123“, true和 false
System.out.println(coll); //调用toString方法
System.out.println(coll.remove(new Person("Jerry", 13)));// 因为Person类没有重写equals方法,所以删除不成功,返回false。
System.out.println(coll);
// removeAll(Collection coll),取当前集合的差集,返回一个布尔类型变量
Collection collection = Arrays.asList(123,4567);
System.out.println(coll.removeAll(collection)); //false,因为存在coll中没有的元素
System.out.println(coll); //输出不带123 的子集。
}
取两个集合的交集
- boolean retainAll(Collection c):把交集的结果存在当前集合中,不影响c
@Test
public void test3(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new Person("Jerry",13));
coll.add(new String("Tom"));
coll.add(false);
//retainAll(Collection c) 交集,获取当前集合和c集合的交集,并返回给当前集合,不影响c
Collection collection = Arrays.asList(123,456,789);
coll.retainAll(collection);
System.out.println(coll); // [123, 456]
}
集合是否相等
- boolean equals(Object obj)
@Test
// equals(object obj),要想返回true,需要当前集合和形参集合都相同。
public void test4(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new String("Tom"));
coll.add(false);
Collection coll1 = new ArrayList();
coll1.add(123);
coll1.add(456);
coll1.add(new String("Tom"));
coll1.add(false);
System.out.println(coll.equals(coll1)); //true
}
转成对象数组
- Object[] toArray()
获取集合对象的哈希值
- hashCode()
@Test
public void test5(){
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new String("Tom"));
coll.add(false);
//hashCode() 获取集合对象的哈希值
System.out.println(coll.hashCode());//7639761
// 集合---》数组 toArray(), 返回Object[]数组
Object[] objects = coll.toArray();
for(int i = 0; i < objects.length; i++){
System.out.println(objects[i]);
}
//拓展: 数组--》集合
List strings = Arrays.asList(new String[]{"AA", "BB", "CC"});// 返回一个List
System.out.println(strings);//[AA, BB, CC]
List list = Arrays.asList(new int[]{123,456});
System.out.println(list);//[[I@35fc6dc4],基本类型数组不能放到集合里,要用new Integer[]
}
}
03 Iterator迭代器接口
- Iterator对象称为迭代器(设计模式的一种),主要用于遍历Collection 集合中的元素。
- GOF给迭代器模式的定义为:提供一种方法访问一个容器(container)对象中各个元素,而又不需暴露该对象的内部细节。迭代器模式,就是为容器而生。类似于“公交车上的售票员”、“火车上的乘务员”、“空姐”。
- Collection接口继承了java.lang.Iterable接口,该接口有一个iterator()方法,那么所有实现了Collection接口的集合类都有一个iterator()方法,用以返回一个实现了Iterator接口的对象。
- Iterator 仅用于遍历集合,Iterator本身并不提供承装对象的能力。如果需要创建Iterator 对象,则必须有一个被迭代的集合。
- 集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前。
3.1 Iterator遍历Collection
遍历
- iterator():返回迭代器对象,用于集合遍历
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
// 集合元素的遍历操作,使用迭代器Iterator接口
public class IteratorTest {
@Test
public void test1() {
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new String("Tom"));
coll.add(false);
// 新建iterator接口
Iterator iterator = coll.iterator();
// 遍历方式一
//System.out.println(iterator.next());//123,next方法用于按顺序取元素
// System.out.println(iterator.next()); //456
// 遍历方式二
// for(int i = 0; i < coll.size(); i++){
// System.out.println(iterator.next());
// }
//遍历方式三,推荐方式
while (iterator.hasNext()) { //这种循环条件不会报异常
System.out.println(iterator.next());
}
}
3.2 两种典型错误写法
@Test
public void test2() {
// 以下是错误遍历方式
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new String("Tom"));
coll.add(false);
Iterator iterator = coll.iterator();//返回迭代器对象,每调用一次都会返回新的迭代器对象
// 错误方式一,这种方法使指针下移了两次,next()每调用一次,指针先下移,并将值返回
//while(iterator.next() != null){
// System.out.println(iterator.next());
//}
// 错误方式二;
while (coll.iterator().hasNext()) {
System.out.println(coll.iterator().next()); //每次新建都会返回全新的迭代器,默认游标在-1位置
}
}
3.3 Iterator执行原理
3.4 Iterator中 remove()的使用
- Iterator可以删除集合的元素,但是是遍历过程中通过迭代器对象的remove方法,不是集合对象的remove方法。
- 如果还未调用next()或在上一次调用next方法之后已经调用了remove方法,再调用remove都会报IllegalStateException。
@Test
public void test3() {
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new String("Tom"));
coll.add(false);
// remove 在遍历时删除集合中的元素,通过Iterator调用
// 删除coll中的"Tom"
Iterator iterator = coll.iterator();
while (iterator.hasNext()) { //这种循环条件不会报异常
Object obj = iterator.next();
if ("Tom".equals(obj)) {
iterator.remove();
}
}
Iterator iterator1 = coll.iterator();
while (iterator1.hasNext()) {
System.out.println(iterator1.next()); //输出没有Tom了
}
}
3.5 用foreach遍历集合或数组对象
- Java 5.0 提供了foreach循环迭代访问Collection和数组。
- 遍历操作不需获取Collection或数组的长度,无需使用索引访问元素。
- 遍历集合的底层调用Iterator完成操作。
- foreach还可以用来遍历数组。
@Test
public void test1(){
// 现有一个集合
Collection coll = new ArrayList();
coll.add(123);
coll.add(456);
coll.add(new String("Tom"));