Java集合的引入
- 数组,集合都是对多个数据进行存储操作的,简称容器。
- 这里的存储指的是内存层面的存储,不是持久化存储(txt,avi,jpg,数据库)
使用数组的缺点
- 数组一旦指定长度,长度就确定了,不可以更改
- 删除,增加元素时,效率低
- 数组中实际元素的数量是没有办法获取,没有提供对应的方法或者属性获取
- 数组存储是有序可重复的,对于无序的,不可重复的数组不能满足要求。
集合框架
导包
import java.util.Collection;
Collection常用功能
public boolean add(E e)把给定的对象添加到当前集合中
public void clear()清空集合中所有的元素
public boolean remove(E e)把给定的对象在当前集合中删除
public boolean contains(E e)判断当前集合中是否包含给定的对象
public boolean isEmpty()判断当前集合是否为空
public int size()返回集合中元素的个数
public Object[] toArray()把集合中的元素,存储到数组中
Collection接口中有一个方法,叫iterator(),这个方法返回的就是迭代器的实现类对象
public static void shuffle(List<?> list)使用指定的随机源对指定列表进行置换。会随机的打乱集合中元素的顺序
public static<T>boolean addAll(Collection<T>c,T...elements)往集合当中添加一些元素
public static <T>void sort(List<T> list)将集合中元素按照默认规则排序
注意sort方法的使用前提,被排序的集合里边存储的元素,必须实现Comparable,重写接口中的方法compareTo定义排序的规则
public static<T>void sort(List<T>list,Comparator<? super T>)将集合中元素按照指定规则排序
Iterator迭代器
导包
import java.util.Iterator;
常用方法
boolean hasNext()如果仍有元素可以迭代,则返回true,没有就返回false
E next()返回迭代的下一个元素
增强for循环
新for循环必须有被遍历的目标。目标只能是Collection或者是数组。新式for仅仅作为遍历操作出现。
格式
for(元素的数据类型 变量:Collection集合or数组){
...
}
泛型
泛型是一种未知的数据类型,当我们不知道使用什么数据类型的时候,可以使用泛型,泛型也可以看出数一个变量,用来接受数据类型。
例如:ArrayList集合在定义的时候,不知道集合中都会存储什么类型的数据,所以类型使用泛型
ArrayListlist =new ArrayList();此时泛型类型为String
泛型的通配符:
?:代表任意的数据类型
使用方式:
不能创建对象使用,只能作为方法的参数使用
List集合
List是有序的集合,用户可以根据元素的整数索引访问元素,允许重复的元素。
List接口中带索引的方法(特有)
public void add(int index,E element)将指定的元素,添加到该集合中的指定位置上
public E get(int index)返回集合中指定位置的元素
public E remove(int index)移除列表中指定位置的元素,返回的是被移除的元素
public E set(int index,E element)用指定元素替换集合中指定位置的元素,返回值的更新前的元素
注意:操作索引的时候,一定要防止索引越界异常
IndexOutOfBoundsException:索引越界异常,集合会报
ArrayIndexOutOfBoundsException:数组索引越界异常
StringIndexOutOfBoundsException:字符串索引越界异常
ArrayList底层为数组,元素增删慢,查找快。
Vector集合,最早期的集合,底层为数组,单线程,速度慢
LinkedList集合使用的是链表结构,元素增删快,查找慢。
LinkedList常用方法
public void addFirst(E e)将指定元素插入此列表的开头
public void addLast(E e)将指定元素添加到此列表的结尾
public void push(E e)将元素推入此列表所表示的堆栈。此方法等效于addFirst(E)
public E getFirst()返回此列表的第一个元素
public E getLast()返回此列表的最后一个元素
public void clear()清空所以元素
public E removeFirst()移除并返回此列表的第一个元素
public E removeLast()移除并返回此列表的最后一个元素
public E pop()从此列表所表示的堆栈弹出一个元素。此方法相当于removeFirst
Set接口
继承了Collection接口
Set接口的特点:
- 不允许存储重复的元素
- 没有索引的方法,也不能使用普遍的for循环遍历
HashSet接口的特点:
- 不允许存储重复的元素
- 没有索引的方法,也不能使用普遍的for循环遍历
- 是一个无序的集合,存储元素和取出元素的顺序有可能不一致
- 底层是一个哈希表结构(查询的速度非常的快)
哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来得到地址,不是数据实际存储的物理地址)
hashCode方法的源码
public native int hashCode();
native代表该方法调用的是本地操作系统的方法
Set集合不允许添加重复元素的原理
add方法会先调用元素的hasCode方法,计算哈希值,若没有相同的哈希值则直接将元素加入到集合当中。若有相同的哈希值,发现有哈希冲突,调用equals方法比较哈希值相同的元素,若true则不会添加到集合中,反之则加到集合中。
LinkedHashSet集合特点:
底层是一个哈希表(数组+链表/红黑树)+链表,多了一条链表记录元素的存储顺序,保证元素有序
可变参数
使用前提:当方法的参数列表数据类型已经确定,但是参数的个数不确定
使用格式:定义方法时使用
修饰符 返回值类型 方法名(数据类型…变量名){}
如:public static void demo(int…ary)
可变参数的原理:
可变参数底层是一个数组,根据传递参数个数不同,会创建不同长度的数组,来存储这些参数
传递的参数个数,可以是0个(不传递),1,2…多个
使用注意事项:
- 一个方法的参数列表,只能有一个可变参数
- 如果方法的参数有多个,那么可变参数必须写在参数列表的末尾
Map集合
Map中的集合,元素是成对存在的(理解为夫妻)。每个元素由键与值两部分组成,通过键可以找对所对应的值。
Map集合的特点:
- Map集合是一个双列集合,一个元素包含两个值(一个key,一个value)
- Map集合中的元素,key和value的数据类型可以相同,也可以不同
- Map集合中的元素,key是不允许重复的,value是可以重复的
- Map集合中的元素,key和value是一1对应
HashMap集合的特点:
- HashMap集合底层是哈希表:查询的速度特别的快
- HashMap集合是一个无序的集合,存储元素和取出元素得到顺序有可能不一致
LinkedHashMap的特点:
- LinkedHashMap集合底层是哈希表+链表(保证迭代的顺序)
- LinkedHashMap集合是一个有序的集合,存储元素和取出元素的顺序是一致的
Map接口中的常用方法
public V put(K key,V value)把指定的键与指定的值添加到Map集合中
返回值:V
存储键值对的时候,key不重复,返回值V是null
存储键值对的时候,key重复,会使用新的value替换map中重复的value,返回被替换的value
public V remove(Object key)把指定的键,所对应的键值对元素,在Map集合中删除,返回被删除元素的值。
返回值:V
key存在,V返回被删除的值
key不存在,V返回null
public V get(Object key)根据指定的键,在Map集合中获取对应的值
返回值:V
key存在,V返回对应的value值
key不存在,V返回null
boolean containsKey(Object key)判断集合中是否包含指定的键
包含返回true,不包含返回false
Set<K> keySet()返回此映射中包含的键的Set视图
实现步骤:
1.使用map集合中的方法keySet(),把Map集合所有key取出来,存储到一个Set集合中
2.遍历set集合,获取Map集合中的每一个key
3.通过Map集合中的方法get(key),通过key找到value
Set<Map.Entry<K,V>> entrySet()返回此映射中包含的映射关系的Set视图
实现步骤:
1.使用map集合中的方法entrySet(),把Map集合中多个Entry对象取出来,存储到一个Set集合中
2.遍历set集合,获取每一个Entry对象
3.使用Entry对象中的方法getKey()和getValue()获取键与值
HashMap存储自定义类型键值
key如果是自定义类型,就必须重写hashCode方法和equals方法,以保证key的唯一
Hashtable:底层是一个哈希表,是一个线程安全的集合,是单线程集合,速度慢,不可以存储null值,null键。Hashtable的子类Properties集合是唯一和IO流结合的集合
HashMap:底层是一个哈希表,是一个线程不安全的集合,是多线程集合,速度快,可以存储null值,null键
JDK9的新特性:
static <E>List<E> of(E...elements)
使用前提:
当集合中存储的元素的个数已经确定了,不在改变时使用
注意:
1. of方法只适用于List接口,Set接口,Map接口,不适用于接接口的实现类
2. of方法的返回值是一个不能改变的集合,集合不能再使用add,put方法添加元素,会抛出异常
3. Set接口和Map接口在调用of方法的时候,不能有重复的元素,否则会抛出异常
Properties集合
Properties类表示一个持久的属性集,Properties可保存在流中或从流中加载
Properties集合是一个双列集合,key和value默认都是字符串
Properties集合特有方法
Object setProperty(String key,String value)调用Hashtable的方法put
String getProperty(String key)通过key找到value,相当于Map集合的get(key)
Set<String> stringPropertyNames()返回此属性列表中的键集,相当于Map集合中的keySet方法
使用Properties集合中的方法store,把集合中的临时数据,持久化写到硬盘中存储
void store(OutputStream out,String comments)
void store(Writer writer,String comments)
参数:
OutputStream字节输出流,不能写中文
Writer字符输出流,可以写中文
comments:注释,说明作用,不能写中文
使用步骤:
1.创建Properties集合对象,添加数据
2.创建字节输出流/字符输出流对象,构造方法中绑定要输出的目的地
3.使用Properties集合中的方法store,把集合中的临时数据,持久化写入到硬盘中存储
4.释放资源
使用Properties集合中的方法Load,把硬盘中保存的文件(键值对),读取到集合中使用
void load(Inputstream instream)
void load(Reader reader)
使用步骤:
1.创建Properties集合对象
2.使用Properties集合对象中的方法Load读取保存键值对的文件
3.遍历Properties集合
注意:
1.存储键值对的文件中,键与值默认的连接符号可以使用=,空格(其他符号)
2.存储键值对的文件中,可以使用#进行注释,被注释的键值对不会再被读取
3.存储键值对的文件中,键与值默认都是字符串,不用再加引号