目录
二、使用 Iterator接口遍历Collection 集合元素
一、Java集合框架概述
1、Collection接口:单列数据,定义了存取一组对象的方法的集合。
- List:元素有序、可重复的集合。
- Set:元素无序、不可重复的集合。
二、使用 Iterator接口遍历Collection 集合元素
Iterator : Iterator对象称为迭代器(设计模式的一种),主要用于遍历 Collection 集合中的元素。
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* @author hedong
* @version 1.0
* @date 2020/4/9 18:56
*/
public class CollectionTest {
public static void main(String[] args) {
//new一个具体的实现类
Collection c1 = new ArrayList();
//往集合中添加三个数据
c1.add("hedong");
c1.add("zhangsan");
c1.add("liming");
//返回c1的迭代器
Iterator iterator = c1.iterator();
//遍历集合
while(iterator.hasNext()){//hasNext():判断是否还有下一个元素
Object obj = iterator.next();//next():指针下移 ,将下移以后集合位置上的元素返回
System.out.println(obj);
}
}
}
注意:hasNext()仅判断是否还有下一个元素,只有执行了next()指针才会下移并返回该位置上的元素。
三、foreach遍历集合和数组
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
* @author hedong
* @version 1.0
* @date 2020/4/9 18:56
*/
public class CollectionTest {
public static void main(String[] args) {
//new一个具体的实现类
Collection c1 = new ArrayList();
//往集合中添加三个数据
c1.add("hedong");
c1.add("zhangsan");
c1.add("liming");
//foreach内部任然是使用的iterator实现
//for(要遍历元素类型 局部变量:需要遍历的集合对象)
for (Object obj:c1) {
System.out.println(obj);
}
}
}
注意:foreach遍历方式内部仍然使用Iterator迭代器实现
四、Collection接口的子接口——List接口
List接口是Collection接口的子接口,它包括三个常用实现类:ArrayList、LinkedList和Vector。List集合是有序的,可重复的。
ArrayList和LinkedList的异同: |
二者都线程不安全,相对线程安全的Vector,执行效率高。
此外,ArrayList底层
是基于动态数组的数据结构,
LinkedList基于链表的数据结构。对于
随机访问get
和
set
,
ArrayList
觉得优于
LinkedList
,因为
LinkedList要移动指针。对于新增
和删除操作add(
特指插入
)
和
remove
,
LinkedList
比较占优势,因为
ArrayList要移动数据。
|
ArrayList和Vector的区别: |
Vector和
ArrayList
几乎是完全相同的
,
唯一的区别在于
Vector
是同步类
(synchronized),属于
强同步类。因此开销就比ArrayList
要大,访问要慢。正常情况下
,
大多数的
Java程序员使用
ArrayList而不是
Vector,
因为同步完全可以由程序员自己来控制。
Vector每次扩容请求其大
小的2
倍空间,而
ArrayList
是
1.5
倍。
Vector
还有一个子类
Stack。
|
五、Collection接口的子接口——Set接口
Set接口是Collection接口的子接口,它包括三个常用实现类:HashSet、LinkedHashSet(HashSet的子类)和TreeSet。Set集合是无序的,不可重复的。
注意:这里的“无序”不是说每次Set集合打印出来的元素顺序都不一样,而是,每次往Set集合中存放元素时,元素并不是根据底层数组索引顺序存放的,存放位置由哈希值决定。同理,List集合中所谓的“有序”是指元素是根据底层数组索引顺序存放。也就是说,有序或者无序是针对添加时而言。
- HashSet:Set接口的主要实现类,是线程不安全的,可存储null值。
- LinkedHashSet:是HashSet的子类,遍历其内部数据时可按照添加时顺序输出。(注意:这并不意味着“有序”)
- TreeSet:可根据添加对象的指定属性进行排序。所以TreeSet集合中添加的数据必须为相同类的对象
添加元素的过程(以HashSet为例):
1、向HashSet集合中添加元素a
2、调用元素a所在类的hashCode()方法,计算a的哈希值
3、根据计算的哈希值再调用某种算法计算出在HashSet底层数组中的存放位置,即索引位置
4、判断该位置上是否已经有了元素
- 若该位置没有其他元素:直接添加元素a成功
- 若该位置已经有了其他元素b:则比较元素a和b的哈希值,若哈希值不相同,则添加元素a成功;若哈希值相同,则调用元素a所在类的equals()方法,若返回true,则添加失败,返回false,则添加成功。
注意:如果位置上已经有了元素,后面在这个位置上继续添加的元素将以链表方式存储。
六、Map接口及其多个实现类
Map集合用于存储双列数据,即key——value数据。他包括HashMap、LinkedHashMap、TreeMap、Hashtable、Properties多个实现类。
- HashMap:Map的主要实现类,线程不安全、高效,key和value可以为null。
- LinkedHashMap:HashMap的子类,可以在遍历Map元素时按照添加时的顺序输出。
- TreeMap:可以进行排序。
- Hashtable:Map古老的实现类,线程安全,效率低,key和value不可以为null。
- Properties:Hashtable的子类,常用于处理配置文件,key和value都是string类型。
Map结构的理解:
- map中的key:无序的、不可重复的,使用Set存储key。
- map中的value:无序的,可重复的,使用Collection存储value。
- map中的Entry:一个键值对key—value构成一个Entry对象,无序的,不可重复的,使用Set存储Entry对象。
HashMap底层实现原理:
实例化Map对象后,底层将创建一个Entry 数组,当添加一个元素(key-value)时,就首先计算元素key的hash值,以此确定插入数组中的位置,如果这个位置没有元素,则插入成功;如果这个位置已经有了元素,则比较它们的哈希值,如果哈希值不同,则以链表的形式链在这个元素旁边;如果哈希值也相同,则调用equals()比较,若为false,则同样以链表的形式链在旁边,若为true,则覆盖它的值。