基础篇——集合框架
写代码的四点:
1.明确需求。要做什么?
2.分析思路。要怎么做?(1,2,3……)
3.确定步骤。每一个思路要用到哪些语句、方法和对象。
4.代码实现。用具体的语言代码将思路实现出来。
学习新技术的四点:
1.该技术是什么?
2.该技术有什么特点?(使用需注意的方面)
3.该技术怎么使用?(写Demo)
4.该技术什么时候用?(在Project中的使用场景 )
----------------------早计划,早准备,早完成。-------------------------
集合框架概述:
在实际的使用中,我们有了更多的需求,有了更多的容器(每个容器都有自己的数据结构,因此其功能也不同),在不断向上抽取的过程中,出现了体系,最终形成了集合框架。
集合框架是为了表示和操作集合而规定的一种统一的标准的体系结构,任何集合框架都包含三大块内容:对外的接口、接口的实现和对集合运算的算法。
1.接口:即表示集合的抽象数据类型,例如Collection、List、Set、Map等。
之所以定义多个接口,是为了以不同的方式操作集合对象。
接口提供了让我们对集合中所表示的内容进行单独操作的可能。
2.实现(类):即集合框架中接口的具体实现,例如ArrayList、HashSet、HashMap等。
实际上它们就是那些可复用的数据结构。
3.算法:在一个实现了某个集合框架中的接口的对象身上,完成某种有用的计算的方法。
例如:搜索、排序等,这些算法通常是多态的,因为相同的方法,
可以在同一个接口被多个类实现时,有不同的表现。
实际上算法就是可复用的函数。
集合框架的运用减少了设计辛劳、提高了速度质量、提高了复用性,再经过程序员合理的利用,已经成为了软件开发中必不可少的强大工具。
注意:1.集合中存储的都是对象的引用地址;
2.集合中不能存储基本数据类型,jdk1.5后可以这么写,
但是存储的还是对象(基本数据类型包装类对象)。
3.集合存储的时候自动提升为Object类型,取出的时候如果需要使用元素的
特有内容,必须进行向下转型。
Collection(集合)
概述:可以存放一组数据的数据结构,这种数据结构称为Collection集合,是一种容器。
1.Collection是一个接口,其定义了集合的相关功能方法。
2.Collection接口是Set、List、Queue接口的父接口。
Set:
是对Collection的一种扩展,方法和Collection一致。
称为不可重复集,该集合中不允许存放重复的元素,是无序的集合。
Set集合可以通过foreach和Iterator遍历集合中的元素。
注:重复的元素指的并非是同一个元素,而是指equals方法比较结果为true的元素。
常用的实现类为HashSet和TreeSet:
1.HashSet;
a.底层数据结构是哈希表结构,所以导致该集合存储元素的时候是无序的,
如果想按照自身排序,需重写父类中的hashCode()、equals()方法;
b.线程是不同步的,所以效率方面比较高效;
2.TreeSet;
a.底层数据结构是二叉树结构,可以对集合中的元素进行排序,
也可以根据指定比较器进行排序,需在该集合的构造函数中传入比较器参数。
List:
是对Collection的一种扩展。
用于定义线性表数据结构,称为可重复集,该集合中允许存放重复的元素。
通常表示一个列表(数组、队列、链表、栈等),是有序的集合。
集合中的元素是可以重复的,通过索引就可以精确的操作集合中的元素。
List集合可以通过for、foreach和Iterator遍历集合中的元素。
注:重复的元素指的并非是同一个元素,而是指equals方法比较结果为true的元素。
常用的实现类为ArrayList和LinkedList,还有不常用的Vector(已过时):
1.ArrayList:更适合于随机访问;
a.底层数据结构是数组结构,所以查询速度快,增删速度慢;
b.因为该集合底层为数组结构,所以当存储的元素个数大于自定义数组的长度时,
集合会自动以原有数组长度的50%延长,并将原数组中的元素复制到该数组中。
c.安全性方面线程不安全、线程不同步;
2.LinkedList:更适合于插入和删除;
a.底层数据结构是链表结构,所以查询速度慢,增删速度快;
b.特有方法:addFirst()、addLast()可以将指定元素添加到列表开头和结尾处;
getFirst()、getLast()可以获取列表中的第一个元素和最后一个元素;
removeFirst()、removeLast()可以删除列表中的第一个元素和最后一个元素。
c.安全性方面线程不安全、线程不同步;
3.Vector(已过时);jdk1.2版本后被ArrayList集合取代。
a.底层是数组结构;
b.与ArrayList集合不同之处在于,安全性方面线程安全、线程同步,所以效率低,
数组自动扩展以原有数组长度的100%延长。
Queue(队列):
JDK1.5新增,
与Set、List集合类的主要区别在于:Queue主要用于存储数据,而不是处理数据。
Set和List的区别:
1.Set接口实例存储的是无序的、不重复的元素,无索引;
List接口实例存储的是有序的、可重复的元素,含有索引。
2.a.Set检索效率低,删除和插入效率高,插入和删除不会引起元素位置改变。
实现类有HashSet、TreeSet;
b.List检索效率高,删除和插入效率低,插入和删除会引起元素位置改变。
可以动态增长,根据实际存储的数据的长度自动增长List的长度。
实现类有ArrayList、LinkedList、Vector(已过时);
Map
概述:可以以键值对(key-value)的形式存储数据的数据结构,这种数据结构称为Map。
Map是一种把键对象和值对象进行关联的容器。
1.Map存入的元素的key不能重复(不能包含两个equals为true的key),
value可以重复。
2.Map存入的元素的key、value的类型均为引用类型(基本数据类型的包装类,
例如:String、Integer)。但是为了保证在使用时不会造成数据混乱,通常使用
泛型去约束key、value的类型。
3.Map中的键值对以Entry类型的对象实例形式存在;
4.Map接口提供了返回key值集合、value值集合、Entry值集合的方法;
常用的实现类为HashMap和TreeMap,还有不常用的HashTable(已过时):
HashMap:是一个常用的Map的子类实现,使用散列算法实现。
1.底层数据结构为哈希表结构,无序的;
2.可以存入null值和null键,线程不同步;
注:a.哈希算法hash也称散列,结果叫哈希值。数组中存储的都是元素与哈希值
的对应关系,该数组称为哈希表,查询速度比数组快,重复元素存不进去,
保证元素的唯一性。
b.哈希冲突怎么解决?元素的哈希值(hashcode())一致了,会再次判断元素
的内容是否相同(equals()),如果equals返回true,表示两个元素相同;
如果返回false,表示两个元素不相同,继续通过算法算出位置进行存。
TreeMap:
1.底层数据结构为二叉树结构,默认是升序的;
2.线程不同步,在构造函数中传入比较器参数,可以用于Map集合中键值进行排序;
HashTable:在jdk1.2版本后被HashMap取代;
1.底层数据结构为哈希表结构;
2.不能存入null值和null键,线程同步;
List和Map的区别:
1.List是存储单列数据的集合;
Map是存储键值对的双列数据的集合;
2.List中存储的数据是有序的,并且允许重复;
Map中存储的数据是无序的,键不能重复,值可以重复;
Iterator(迭代器)
遍历一个集合中的元素,通常使用以下三种方式:
1.for循环;
2.foreach增强for循环;
3.Iterator迭代器:使我们能够通过循环来得到或删除集合中的元素,不需要担心
在遍历过程中会超出集合的长度。
Iterator是一个对象,实现了Iterator接口或ListIterator接口。
ListIterator继承了Iterator,以允许双向遍历列表和修改元素。
Set集合可以通过foreach和Iterator遍历集合中的元素。
//创建Set集合
Set<String> set = new HashSet<>();
// Set<String> set = new TreeSet<>();
set.add("李四");
set.add("张三");
set.add("王麻子");
//通过Iterator遍历Set集合中的元素
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
String setData = iterator.next();
LogUtil.e("set集合中的元素", setData);
}
//通过foreach(增强for循环)遍历Set集合中的元素
for (String setData : set) {
LogUtil.e("set集合中的元素++++", setData);
}
List集合可以通过for、foreach和Iterator遍历集合中的元素。
//创建List集合
List<String> list = new ArrayList<>();
// List<String> list = new LinkedList<>();
list.add("李四");
list.add("张三");
list.add("王麻子");
//通过for循环遍历集合中的元素
for (int i = 0; i < list.size(); i++) {
LogUtil.e("List集合中的元素", list.get(i));
}
//通过foreach(增强for循环)遍历集合中的元素
for (String listData : list) {
LogUtil.e("List集合中的元素+++", listData);
}
//通过Iterator遍历集合中的元素
Iterator<String> iterator = list.iterator();
while (iterator.hasNext()){
LogUtil.e("List集合中的元素---", iterator.next());
}
Map接口中没有迭代器,通过Set集合遍历Map中的键值对。
//创建Map
Map<String, String> map = new HashMap<>();
// Map<String, String> map = new TreeMap<>();
map.put("name", "张三");
map.put("gender", "男");
map.put("age", "25");
//map.keySet()获取到所有的键,存储到set集合中,并返回该集合。
//因为Set有迭代器,每次迭代出来的是一个键,再根据键来得到值。
Set<String> mapSet = map.keySet();
for (String key : mapSet) {
LogUtil.e("Map中的键值对", key + "," + map.get(key));
}
//map.entrySet()获取到所有键值对的映射关系,存储到set集合中,
//每次迭代出来的是一个映射关系,
//从这个映射关系中既可以得到键,也可以得到值。
Iterator<Map.Entry<String, String>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
LogUtil.e("Map中的键值对+++", entry.getKey() + "," + entry.getValue());
}
for (Map.Entry<String, String> stringStringEntry : map.entrySet()) {
LogUtil.e("Map中的键值对---", stringStringEntry.getKey() + "," + stringStringEntry.getValue());
}
//map.values()获取到所有的值,无法遍历key
Collection<String> values = map.values();
for (String value : values) {
LogUtil.e("Map中的值", value);
}
Collection和Collections的区别:
1.Collection是集合类的上级接口,继承它的接口主要有Set和List。
2.Collections是针对集合类的帮助类,提供了一系列静态方法
实现对各种集合的搜索、排序、线程安全化等操作。
集合和数组的区别:
1.集合的长度可变,但是数组的长度固定;
2.数组只能通过下标访问元素,下标类型只能是数字型;
而有的集合可以通过任意类型查找所映射的具体对象;
3.数组中存储的是同一类型的元素,可以存储基本数据类型值;
集合存储的是对象,而且对象的类型可以不一致;