collection集合(单列集合)
单列集合
- 概述
java提供的一种容器,可以用来存储多个数据- 数组长度不变,集合长度可变
- 数组储存同一类型的元素,可以存储基本数据类型。集合只能储存对象,而且类型可以不一致。开发中对象比较多时,使用集合进行存储
- 框架介绍
- 常用功能
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();
- Iterator接口(java.util)
- 常用方法
boolean hasNext();//判断是否有下一个元素迭代 E next();//返回下一个元素
- 使用步骤
- 使用集合的iterator()方法获取迭代器的实现对象,使用Iterator接口接受(多态)
- 使用Iterator接口中的方法hasNext方法判断是否有下一个元素
- 使用Iterator接口中的next方法取出集合中的下一个元素
//取元素是一个重复的过程,而且不知道是否还有元素,所以首选dowhile循环,循环结束的条件:hasNext()返回false Iterator<String> it = coll.iterator(); while(it.hasNext()){ String e = it.next(); System.out.printlb(e); }
- 增强for
专门用来遍历数组和集合,内部原理是个迭代器,所以不能对集合中的元素进行增删操作。for(String s : coll){ System.out.println(s)
- 遍历集合的两种方法
- 迭代器
- 增强for
泛型
- 概述
- 创建集合对象使用范型的好处
- 使用泛型
- 好处:
- 避免了类型转换的麻烦,存储什么类型,取出就是什么类型
- 把运行期异常转为编译期异常
- 缺点:泛型什么类型,就只能存储什么类型
- 好处:
- 不使用泛型
- 好处:默认Object类,可以存储任意类型
- 缺点:不安全,会引发异常
- 使用泛型
- 泛型的定义
- 定义含有泛型的类
- 泛型是一个未知的数据类型,当不确定什么数据类型时,可以使用泛型
- 泛型可以接受任意的数据类型,可以使用String,Student等
- 创建对象的时候确定泛型的类型
- 定义含有泛型的方法
- 定义含有泛型的接口
- 第一种使用方式:定义接口的实现类,实现接口,指定接口的泛型
- 第二种使用方式:接口使用什么泛型,实现类就使用什么泛型,类跟着接口走。那么创建对象的时候在确定泛型的类型
- 定义含有泛型的类
//类名<泛型>
//方法名(泛型)
//接口名<泛型>
- 泛型通配符
- 当使用泛型或接口时,传递的数据中,泛型不确定,可以使用通配符<?>来表示。但是一旦使=使用通配符,只能使用Object的共性方法,集合元素自身方法无法使用
- 通配符的高级使用——受限泛型
public static void getElement(Collection<?> coll){}
单列案例
斗地主
数据结构
- 栈(Stack)
又称堆栈,运算受限的线性表 - 队列(Queue)
简称队,运算受限的线性表 - 数组(Array)
有序的元素序列,在内存开辟的一段连续的空间
- 链表(Linked list)
由一系列结点node组成,运行时动态生成。每个结点包括两个部分:数据域,与指针域。- 分为单向链表和双向链表(有序)
- 分为单向链表和双向链表(有序)
- 红黑树
List集合(java.util)
- 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)
- 特点
- ArrayList集合
- 集合存储数据的结构是数组结构,增删慢,查找快
日常开发使用最多的功能是查询数据,遍历数据,所以很常用 - ArrayList不是同步的,是多线程的
- 集合存储数据的结构是数组结构,增删慢,查找快
- LinkedList集合
- 集合存储的结构是链表(双向),方便元素增删。
- 里面有大量操作头尾的方法
public void addFirst(E e);
public void addLast(E e);
public void push(E e);
public E getFirst();
public E getLast();
public E removeFirst();
public E removeLast();
public E pop();
public bool isEmpty();
public void clear();
- Vector集合
是同步的,可以实现List接口。被ArrayList取代了,因为是单线程的。
Set集合()(java.util)
-
Set接口的特点
- 不允许存储重复的元素
- 没有索引,没有带索引的方法,也不能用普通的for循环遍历(使用迭代器和增强for)
-
HashSet集合(java.util)
实现了Set接口- 特点
- 无序集合
- 底层是一个哈希表结构(查询速度非常快)
- 不允许存储重复的元素
- 没有索引,没有带索引的方法,也不能用普通的for循环遍历(使用迭代器和增强for)
- 特点
-
Hash值
- 十进制的的整数,由系统随机给出(对象的地址值,但是是一个逻辑地址,模拟出来得到的地址,不是数据实际存储的物理地址)。
- 在Object类有一个方法,可以获取对象的Hash值。
//hashCodef方法的源码 public native int hashCode(); //native:代表该方法调用的是本地操作系统的方法 //toString方法的源码 return getClass().getName() + "@" + Integer.toHexString(hashCode()); //String类的Hash值:String类重写Object类的hashCode方法
-
Hashset集合存储数据的结构(哈希表)
- 哈希表=数组+链表
哈希表=数组+红黑树(1.8之前只有数组+链表) - 特点:查询速度快
- 哈希表=数组+链表
-
Set集合存储元素不重复的原理
-
HashSet存储自定义类型元素
-
给HashSet中存放自定义类型元素时,需要重写对象中hashCode方法和equals方法,建立自己的比较方式,才能保证HashSet集合的对象唯一
-
LinkedHashSet集合
- java.util.LinkedHashSet集合 extends HashSet集合
- 特点:底层是一个哈希表(数组+链表/红黑树)+链表(记录元素的存储数据),保证元素有序
-
可变参数
- JDK1.5之后出现的新特性:当方法的参数李彪数据类型已经确定,但是个数不确定,可使用可变参数。
- 格式:修饰符 返回值 方法名(数据类型… 变量名){}
- 原理:底层就是一个数组,根据传递参数的不同,会创建不同长度的数组,来储存这些参数。可以是(1~多个)
- 注意事项
- 一个方法的参数列表,只能有一个可变参数
- 如果方法的参数有多个,那么可变参数必须卸载参数列表的末尾
//计算(1~n)整数的方法
public static int add(int...arr){
//定义一个初始化的变量,记录累加求和
int sum = 0;
//遍历数组arr再累加求和
for (int i : arr){
sum += i;
}
return sum;
}
Collections工具类
- 操作集合的工具类
- addAll方法和shuffle方法
//往集合添加多个元素
public static <T> boolean addAll(Collection<T> c,T... element);
//打乱集合顺序
public static void shuffle(List<?> list);
- 第一个sort方法
- 注意事项:
被排序的集合里面存储的元素,必须实现Compareble接口,重写compareTo定义的排序规则
- 注意事项:
//将集合中的元素按照默认规则排序
public static <T> void sort(List<T> list)
//以Person;类为例重写compareTo方法
public class Person implements Comparable<Person>{
@override
public int compareTo(Person o){
//返回0认为元素都是相同的
//自定义比较规则
return this.getAge() - o.getAge();//按年龄升序排序
//规则:自己(this)-参数 升序
// 参数-自己(this) 降序
}
}
- 第二个sort方法
- Comparator和Comparable的区别
Comparable:自己和别人比较,自己需要实现接口,重写比较的规则方法
Comparator:相当于找一个第三方的裁判来比较
- Comparator和Comparable的区别
//将集合按指定规则排序
public static <t> void sort(List<T>,Comparator<? super T>);
//例子
Collection.sort(list1,new Comparator<Interger>(){
@override
public int compara(Interger o1,Interger o2){
return o1-o2;//升序,o2-o1降序
}
});
//自定义类比较
Collection.sort(list2,new Comparator<Student>(){
@override
public Int compara(Student o1,Student o2){
return o1.getAge-o2.getAge;//按年龄升序
}
});
//组合式的拓展
Collection.sort(list2,new Comparator<Student>(){
@override
public Int compara(Student o1,Student o2){
result = o1.getAge-o2.getAge;//按年龄升序
if (result==0){
o1.getName().charAt(0)-o2.getName().charAt();
}
}
});
Map集合(双列集合)
双列集合<K ,V>
- Map集合特点Map<k,v>
- 双列集合,一个元素包含两个值
- key和value数据类型可以相同,也可以不同
- key不允许重复,value可以
- key和value一一对应
- 常用的实现类
- HashMap类<K,V>
- 底层基于哈希表(查询速度特别快)(1.8之后当链表部分大于8则采用红黑树)
- 无序集合
- 不同步,多线程
- 子类LinkedHashMap 有序集合(+链表),保证迭代顺序的有序性
- HashTable类<K,V>
最早期的双列集合
- HashMap类<K,V>
- 常用方法
public V put(K key, V value);//把指定的key和value添加到Map集合中,返回被替换的值
public V remove(Object Key);//删除key指定的值,返回被删除的元素
public V get(Object Key);//返回key指定的值
boolean containsKey(Object o);//包含key则返回true,否则返回false
//以上方法返回的元素如果不存在,则返回null
- Map集合的遍历
- 键找值(keySet()方法)
Map集合中的方法: Set keySet()返回此映射中的包含的键的Set视图- 通过keySet取出所有的key,存储到一个Set集合中
- 遍历Set集合,获取Map集合中每一个key(迭代器和增强for)
- 通过get(key)方法来找到value
- 使用Entry对象(EntrySet()方法→getKey()和getValue方法)
Map→Set< Map.Entry<K,V> >→key和value
- 键找值(keySet()方法)
- HashMap存储自定义类型键值
Map集合保证键唯一,作为key的元素,必须重写hashCode和equals方法,以保证键的唯一 - LinkedHashMap类
有序集合,底层原理:哈希表+链表 - HashTable类
- 实现了Map接口,底层也是一个哈希表。
- 特点
- HashTable是一个线程安全的集合,单线集合,速度慢
- HashTable不能存储
- HashTable集合(HashMap)和Vetor集合(ArrayList)已经被更先进的集合取代了。但HashTable的子类Properties依然活跃在历史的舞台
Properties是唯一一个和IO流相结合的集合
- 练习:计算一个字符串中每个字符出现的次数
双列案例
补充知识
- JDK9对集合的添加
- List,Set,Map接口:增加了静态方法of,一次添加多个元素
使用前提:当集合中存储的元素的个数已经确定,不再改变时使用- of方法只适用于这三个接口,不适用于接口的实现类
- of的返回值是一个不能改变的集合,集合不能再使用add,put方法添加元素,会抛出异常
- Set和Map接口在调用of方法时,不能有重复的元素,否则异常
- List,Set,Map接口:增加了静态方法of,一次添加多个元素
- Debug追踪
框架