在实现方法时,选择不同的数据结构会导致其实现风格以及性能存在很大的差异。
集合接口下面是具体的实现类。
集合&迭代器
在最顶层的父接口Collection中定义了所有子类集合的共同属性和方法,子类集合有各自特有的属性和方法。
- Collection中的常用功能(共有的功能)
boolean add(Object e): 向集合中添加元素
void clear():清空集合中所有元素
boolean contains(Object o):判断集合中是否包含某个元素
boolean isEmpty():判断集合中的元素是否为空
boolean remove(Object o):根据元素的内容来删除某个元素
int size():获取集合的长度
Object[] toArray():能够将集合转换成数组并把集合中的元素存储到数组中
- 迭代器(通用的获取集合中对象的方法) Iterator
java中提供了很多个集合,它们在存储元素时,采用的存储方式不同。我们要取出这些集合中的元素,可通过一种通用的获取方式来完成。
Collection集合元素的通用获取方式:在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。
集合中把这种取元素的方式描述在Iterator接口中。Iterator接口的常用方法如下
hasNext()方法:判断集合中是否有元素可以迭代
next()方法:用来返回迭代的下一个元素,并把指针向后移动一位。
并发修改异常: 迭代器在迭代的时候会复制一个集合副本,在迭代的时候,对集合进行修改,会产生并发修改错误。
集合和迭代在同时进行,并且在比对是否相等,不相等就并发修改错误
并发修改异常产生原因: 当使用迭代器遍历集合的时候,使用了集合中的 增加/删除 方法,导致并发修改异常产生。
并发修改异常解决方案:
A:不使用迭代器遍历集合,就可以在遍历的时候使用集合的方法进行增加或删除
B:依然使用迭代器遍历,那么就需要使用Iterator的子接口ListIterator来实现向集合中添加
增强for&泛型
- 泛型的引入
由于集合可以存储任意类型的对象,当我们存储了不同类型的对象,就有可能在转换的时候出现类型转换异常, 所以java为了解决这个问题,给我们提供了一种机制,叫做泛型.
泛型:是一种广泛的类型,把明确数据类型的工作提前到了编译时期,借鉴了数组的特点
* 泛型好处:
* 避免了类型转换的问题
* 可以减少黄色警告线
* 可以简化我们代码的书写
当类上定义<>的时候就可以使用泛型,例如ArrayList类的定义:
class ArrayList<E>,那么我们在创建ArrayList对象的时候就可以指定<>中E的类型
如: ArrayList<String> al=new ArrayList<String>(),
- 增强for
增强for循环是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部原理其实是个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作。
格式:
for(元素的类型 变量 : 集合或者数组对象) {
可以直接使用变量;
}
它用于遍历Collection和数组。通常只进行遍历元素,不要在遍历的过程中对集合元素进行增删操作。
常见数据结构:
- 数组
数组,采用该结构的集合,对元素的存取有如下的特点:
查找元素快:通过索引,可以快速访问指定位置的元素
增删元素慢 ,每次添加元素需要移动大量元素或这创建新的数组
- 链表
链表,采用该结构的集合,对元素的存取有如下的特点:
A:多个节点之间,通过地址进行连接。例如,多个人手拉手,每个人使用自己的右手拉住下个人的左手,依次类推,这样多个人就连在一起了。
B:查找元素慢:想查找某个元素,需要通过连接的节点,依次向后查找指定元素
C:增删元素快:
增加元素:只需要修改连接下个元素的地址即可。
删除元素:只需要修改连接下个元素的地址即可
-
- 栈&队列
A:堆栈,采用该结构的集合,对元素的存取有如下的特点:
先进后出(即,存进去的元素,要在后它后面的元素依次取出后,才能取出该元素)。
例如,子弹压进弹夹,先压进去的子弹在下面,后压进去的子弹在上面,当开枪时,先弹出上面的子弹,然后才能弹出下面的子弹。
B:队列,采用该结构的集合,对元素的存取有如下的特点:
先进先出(即,存进去的元素,要在后它前面的元素依次取出后,才能取出该元素)。例如,安检。排成一列,每个人依次检查,只有前面的人全部检查完毕后,才能排到当前的人进行检查。
List子体系
- List子体系特点
A:有序的(存储和读取的顺序是一致的)
B:有整数索引
C:允许重复的
- List的特有功能
void add(int index, E element) :将元素添加到index索引位置上
E get(int index) :根据index索引获取元素
E remove(int index) :根据index索引删除元素
E set(int index, E element):将index索引位置的的元素设置为element
- LinkedList特有功能
LinkedList底层使用的是链表结构,因此增删快,查询相对ArrayList较慢
void addFirst(E e) :向链表的头部添加元素
void addLast(E e):向链表的尾部添加元素
E getFirst():获取链头的元素,不删除元素
E getLast():获取链尾的元素,不删除元素
E removeFirst():返回链头的元素并删除链头的元素
E removeLast():返回链尾的元素并删除链尾的元素
总结:
List的常用子类:
* ArrayList
* 底层是数组结构,查询快,增删慢
* LinkedList
* 底层结构是链表,查询慢,增删快
*如何选择使用不同的集合?
* 如果查询多,增删少,则使用ArrayList
* 如果查询少,增删多,则使用LinkedList
* 如果你不知道使用什么,则使用ArrayList
HashSet集合
-
- Set接口的特点
Set体系的集合:
A:存入集合的顺序和取出集合的顺序不一致
B:没有索引
C:存入集合的元素没有重复
- HashSet唯一性原理 哈希值是什么?
规则:新添加到HashSet集合的元素都会与集合中已有的元素一一比较
首先比较哈希值(每个元素都会调用hashCode()产生一个哈希值)
如果新添加的元素与集合中已有的元素的哈希值都不同,新添加的元素存入集合
如果新添加的元素与集合中已有的某个元素哈希值相同,此时还需要调用equals(Object obj)比较
如果equals(Object obj)方法返回true,说明新添加的元素与集合中已有的某个元素的属性值相同,那么新添加的元素不存入集合
如果equals(Object obj)方法返回false, 说明新添加的元素与集合中已有的元素的属性值都不同, 那么新添加的元素存入集合
- Collections中的方法:操作Collection
https://www.cnblogs.com/guweiwei/p/6511974.html
HashMap集合
- Map接口概述
我们通过查看Map接口描述,发现Map接口下的集合与Collection接口下的集合,它们存储数据的形式不同,如下图。
A:Collection中的集合,元素是孤立存在的(理解为单身),向集合中存储元素采用一个个元素的方式存储
B:Map中的集合,元素是成对存在的(理解为夫妻)。每个元素由键与值两部分组成,通过键可以找对所对应的值。
C:Collection中的集合称为单列集合,Map中的集合称为双列集合。
需要注意的是,Map中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。
- Map常用功能
A:映射功能:
V put(K key, V value) : 以键=值的方式存入Map集合
B:获取功能:
V get(Object key): 根据键获取值
int size(): 返回Map中键值对的个数
C:判断功能:
boolean containsKey(Object key): 判断Map集合中是否包含键为key的键值对
boolean containsValue(Object value): 判断Map集合中是否包含值为value键值对
boolean isEmpty(): 判断Map集合中是否没有任何键值对
D:删除功能:
void clear(): 清空Map集合中所有的键值对
V remove(Object key): 根据键值删除Map中键值对
E:遍历功能:
Set<Map.Entry<K,V>> entrySet(): 将每个键值对封装到一个个Entry对象中,再把所有Entry的对象封装到Set集合中返回
Set<K> keySet() : 将Map中所有的键装到Set集合中返回
Collection<V> values(): 返回集合中所有的value的值的集合
- Map的两种遍历方式
利用keySet()方法遍历
public class MapDemo4 {
public static void main(String[] args) {
//创建Map对象
Map<String,String> map = new HashMap<String,String>();
//添加映射关系
map.put("谢婷疯", "张箔纸");
map.put("陈关西", "钟欣桶");
map.put("李亚碰", "王飞");
//遍历Map对象
Set<String> keys = map.keySet();
for (String key : keys) {
String value = map.get(key);
System.out.println("丈夫:" + key + "---" + "媳妇:" + value);
}
}
}
-
-
- 利用entrySet()方法遍历
-
public class MapDemo5 {
public static void main(String[] args) {
//创建Map对象
Map<String,String> map = new HashMap<String,String>();
//添加映射关系
map.put("尹志平", "小龙女");
map.put("令狐冲", "东方菇凉");
map.put("玄慈", "叶二娘");
//获取所有的结婚证对象
Set<Map.Entry<String,String>> entrys = map.entrySet();
//遍历包含了结婚证对象的集合
for (Map.Entry<String, String> entry : entrys) {
//获取每个单独的结婚证对象
//通过结婚证对象获取丈夫和媳妇
String key = entry.getKey();
String value = entry.getValue();
System.out.println("丈夫:" + key + "---" + "媳妇:" + value);
}
}
}
-
- 可变参数
- 知识概述
- 可变参数
当参数不确定的时候, 类型要明确
Java可以把多个参数直接帮我们转成数组
理解: 可变参数本质就是一个长度可变的数组.
格式:
实参: 一个参数一个参数的传递
形参: 类型…变量名
-
-
- 注意
-
在可变参数之后不可以再追加参数
参数的数量定义, 可以给多个甚至也可以一个都不不给
Public static int getSum(int…num){
int sum = 0;
for(int i = 0; i < num.length; i++){
sum+=num[i];
}
return sum;
}