思维导图
一、Collection集合
1、集合体系结构
集合类的特点
提供一种存储空间可变的存储模型,存储的数据容量可以随时发生改变
集合类的体系图
2、Collection集合概述和使用
Collection集合概述
是接口(不能被实例化,只能梳理化它的子类),表示一组对象,对象也称为Collection的元素
重写了toString()
一些Collection 允许有重复元素,一些Collection是有序(List)的(输入顺序为元素顺序);Set 是无序的
JDK 不提供此接口的任何直接实现,提供更具体的子接口(如Set和List)实现
Collection集合基本使用
数组的缺点:长度固定,不可改变;无法求出真实有效数据个数;增删改查比较麻烦
3、Collection集合的常用方法
方法名 | 说明 |
---|---|
boolean add(E e) | 添加元素 |
boolean remove(Object o) | 从集合中移除指定的元素 |
void clear() | 清空集合中的元素 |
boolean contains(Object o) | 判断集合中是否存在指定的元素 |
boolean isEmpty() | 判断集合是否为空 |
int size() | 集合的长度,也就是集合中元素的个数 |
public class CollectionDemo01 {
public static void main(String[] args) {
//创建Collection集合的对象
Collection<Student> c = new ArrayList<Student>();
collection c1 = new ArrayList();
//添加元素:boolean add(E e)
c.add("a");
c.add(stu);
c.addAll(c1)//将c中所有元素添加到c1中
//删除元素:boolean remove(Object o)
c.remove("a");
c.removeAll(c1)//删除c中c1中包含的所有元素
//检测c中是否包含某个指定对象:boolean contains(Object o)
c.contains("a")
c.contains(stu)
//检测集合中是否包含另一个集合的所有元素:boolean containsAll(Object o)
c.contains(c1)
//判断集合是否为空:boolean isEmpty()
c.isEmpty();
//清空集合void clear()
c.clear();
//迭代器:iterator()
iterator iter = c.interator();
//判断集合是否有下一个元素:iter.hasNext() :
while(iter.hasNext()){
String result=(String)iter.next();//取出下一个元素:iter.next();
}
//c中只保留c1的所有元素
c.retainAll(c1)
//获取当前集合之中元素的个数:int size()
c.size();
//将集合转换为数组:Object toArray();
Object[] cc = c.toArray()
//创建学生对象
Student stu=new Student("ww",23)
//输出集合对象
System.out.println(c);
}
}
##
4、Collection集合的遍历
迭代器的介绍
迭代器,集合的专用遍历方式
Iterator<E> iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到
迭代器是通过集合的iterator()方法得到的,所以我们说它是依赖于集合而存在的
Collection集合的遍历
//创建集合对象 Collection<String> c = new ArrayList<>(); //添加元素 c.add("hello"); c.add("world"); c.add("java"); c.add("javaee"); //Iterator<E> iterator():返回此集合中元素的迭代器,通过集合的iterator()方法得到 Iterator<String> it = c.iterator(); //用while循环改进元素的判断和获取 while (it.hasNext()) { String s = it.next(); System.out.println(s); } } }
二、List集合
1、List集合概述和特点
List集合概述
有序集合(也称为序列),用户可以精确控制列表中每个元素的插入位置。用户可以通过整数索引访问元素,并搜索列表中的元素
与Set集合不同,列表通常允许重复的元素
List集合特点
有索引
可以存储重复元素
元素存取有序
2、List集合的特有方法
方法名 | 描述 |
---|---|
void add(int index,E element) | 在此集合中的指定位置插入指定的元素 |
E remove(int index) | 删除指定索引处的元素,返回被删除的元素 |
E set(int index,E element) | 修改指定索引处的元素,返回被修改的元素 |
E get(int index) | 返回指定索引处的元素 |
import java.util.ArrayList;
import java.util.List;
public class Demo1 {
public static void main(String[] args) {
List l = new ArrayList();
List l1= new ArrayList();
// 添加元素
l.add("a");
l.add(2,"b");//添加到指定位置
l.addAll(l1);//添加l1到l
l.addAll(0,l1);//将l1添加到指定位置
//获取指定位置的元素
Object object=l.get(1);
//获取指定对象在集合中的位置(从集合开头往后找第一次出现指定对象的位置):indexof()
int index=l.indexOf("a");
//获取指定对象在集合中的位置(从集合末尾开始往前找第一次出现指定对象的位置):lastIndexof()
int index1=l.lastIndexOf("a");
//删除第一次出现位置的指定对象
l.remove("a");
l.remove(0);//删除指定索引的对象
//替换指定位置的元素
l.set(2,"c");
//截取从第0开始到第3-1个元素(左闭右开)
l.subList(0,3);
}
}
3、List集合遍历
//迭代器方式
Iterator<Student> it = list.iterator();
while (it.hasNext()) {
Student s = it.next();
System.out.println(s.getName() + "," + s.getAge());
}
System.out.println("--------");
//for循环方式
for(int i=0; i<list.size(); i++) {
Student s = list.get(i);
System.out.println(s.getName() + "," + s.getAge());
}
List集合的实现类
1、List集合子类的特点
ArrayList集合
底层是数组结构实现,查询快、增删慢
LinkedList集合
底层是链表结构实现,查询慢、增删快
2、LinkedList集合的特有功能
特有方法
方法名 说明 public void addFirst(E e) 在该列表开头插入指定的元素 public void addLast(E e) 将指定的元素追加到此列表的末尾 public E getFirst() 返回此列表中的第一个元素 public E getLast() 返回此列表中的最后一个元素 public E removeFirst() 从此列表中删除并返回第一个元素 public E removeLast() 从此列表中删除并返回最后一个元素
LinkedList li=new LinkedList();
li.addFirst("a");//最开头添加
li.addLast("w");//最末尾添加
li.remove(1);
li.remove("a");
li.removeFirst();//从此列表中删除并返回第一个元素
三、set集合
1、Set集合概述和特点
Set集合的特点
元素存取无序
没有索引、只能通过迭代器或增强for循环遍历
不能存储重复元素
//创建集合对象
Set set = new HashSet();
//添加元素
set.add("hello");
set.add("world");
set.add("java");
//不包含重复元素的集合
set.add("world");
//remove()不能根据索引删,只能根据内容删
set.remove("hello");
//遍历
for(String s : set) {
System.out.println(s);
}
2、哈希值
哈希值简介
是JDK根据对象的地址或者字符串或者数字算出来的int类型的数值
如何获取哈希值
Object类中的public int hashCode():返回对象的哈希码值
哈希值的特点
同一个对象多次调用hashCode()方法返回的哈希值是相同的
默认情况下,不同对象的哈希值是不同的。而重写hashCode()方法,可以实现让不同对象的哈希值相同
3、HashSet集合概述和特点
HashSet集合的特点
底层数据结构是哈希表
对集合的迭代顺序不作任何保证,也就是说不保证存储和取出的元素顺序一致
没有带索引的方法,所以不能使用普通for循环遍历
由于是Set集合,所以是不包含重复元素的集合
HashSet集合的基本使用
//创建集合对象 HashSet<String> hs = new HashSet<String>(); //添加元素 hs.add("hello"); hs.add("world"); hs.add("java"); //遍历 for(String s : hs) { System.out.println(s); }
4、HashSet集合保证元素唯一性源码分析
HashSet集合保证元素唯一性的原理
1.根据对象的哈希值计算存储位置
如果当前位置没有元素则直接存入
如果当前位置有元素存在,则进入第二步
2.当前元素的元素和已经存在的元素比较哈希值
如果哈希值不同,则将当前元素进行存储
如果哈希值相同,则进入第三步
3.通过equals()方法比较两个元素的内容
如果内容不相同,则将当前元素进行存储
如果内容相同,则不存储当前元素
5、LinkedHashSet集合概述和特点
LinkedHashSet集合特点
哈希表和链表实现的Set接口,具有可预测的迭代次序
由链表保证元素有序,也就是说元素的存储和取出顺序是一致的
由哈希表保证元素唯一,也就是说没有重复的元素
6、Set集合排序
TreeSet集合概述和特点
TreeSet集合概述
元素有序,可以按照一定的规则进行排序,具体排序方式取决于构造方法
TreeSet():根据其元素的自然排序进行排序
TreeSet(Comparator comparator) :根据指定的比较器进行排序
没有带索引的方法,所以不能使用普通for循环遍历
由于是Set集合,所以不包含重复元素的集合
四、数据结构
1、数据结构之栈和队列
栈结构
先进后出
队列结构
先进先出
2、数据结构之数组和链表
数组结构
查询快、增删慢
队列结构
查询慢、增删快
五、Map集合
1、Map集合概述和特点
Map集合概述
interface Map<K,V> K:键的类型;V:值的类型
Map集合的特点
键值对映射关系
一个键对应一个值
键不能重复,值可以重复
元素存取无序
Map集合的基本使用
//创建集合对象 Map<String,String> map = new HashMap<String,String>(); HashMap map=new HashMap(); //V put(K key, V value) 将指定的值与该映射中的指定键相关联 map.put("001","a"); map.put("002","b"); map.put("003","c"); map.put("003","d"); //输出集合对象 System.out.println(map); } }
2、Map集合的基本功能
方法介绍
方法名 说明 V put(K key,V value) 添加元素 V remove(Object key) 根据键删除键值对元素 void clear() 移除所有的键值对元素 boolean containsKey(Object key) 判断集合是否包含指定的键 boolean containsValue(Object value) 判断集合是否包含指定的值 boolean isEmpty() 判断集合是否为空 int size() 集合的长度,也就是集合中键值对的个数 V get(Object key) 根据键获取值 Set<K> keySet() 获取所有键的集合 Collection<V> values() 获取所有值的集合 Set<Map.Entry<K,V>> entrySet() 获取所有键值对对象的集合
//创建集合对象
Map<String,String> map = new HashMap<String,String>();
//V put(K key,V value):添加元素
map.put("001","a");
map.put("002","b");
map.put("003","c");
//V remove(Object key):根据键删除键值对元素(删除不成功不报错)返回值是值
System.out.println(map.remove("001"));
//void clear():移除所有的键值对元素
map.clear();
//boolean containsKey(Object key):判断集合是否包含指定的键
System.out.println(map.containsKey("001"));
//boolean isEmpty():判断集合是否为空
System.out.println(map.isEmpty());
//int size():集合的长度,也就是集合中键值对的个数
System.out.println(map.size());
//V get(Object key):根据键获取值
System.out.println(map.get("001"));
//Set(唯一、无序)<K> keySet():获取所有键的集合
Set<String> keySet = map.keySet();
for(String key : keySet) {
System.out.println(key);
}
//Collection(不唯一、无序)<V> values():获取所有值的集合
Collection<String> values = map.values();
for(String value : values) {
System.out.println(value);
}
//遍历
//1、获取所有键值对对象的集合
Set<Map.Entry<String, String>> entrySet = map.entrySet();
//遍历键值对对象的集合,得到每一个键值对对象
for (Map.Entry me : entrySet) {
//根据键值对对象获取键和值
System.out.println(me.getKey() + "," + me.getValue());
}
//2、先用keySet()取出所有key值,再取出对应value——增强for循环遍历*/
System.out.println("====1、先用keySet()取出所有key值,再取出对应value——增强for循环遍历====");
Set keyset = hashMap.keySet();
for(Object key:keyset){
System.out.println(key+"-"+hashMap.get(key));
}
//3、先用keySet()取出所有key值,再取出对应value——使用迭代器遍历*/
System.out.println("====2、先用keySet()取出所有key值,再取出对应value——使用迭代器遍历====");
Iterator iterator = keyset.iterator();
while(iterator.hasNext()){
Object key = iterator.next();
System.out.println(key+"-"+hashMap.get(key));
}
//4、3、通过entrySet()获得key-value值——增强for循环遍历*/
System.out.println("====3、通过entrySet()获得key-value值——增强for循环遍历====");
Set set = hashMap.entrySet();
for(Object key:set){
Map.Entry entry = (Map.Entry) key;
System.out.println(entry.getKey()+"-"+entry.getValue());
}
//5、通过entrySet()获得key-value值——使用迭代器遍历
System.out.println("====4、通过entrySet()获得key-value值——使用迭代器遍历====");
Set set1 = hashMap.entrySet();
Iterator iterator1 = set1.iterator();
while(iterator1.hasNext()){
Object itset = iterator1.next();
Map.Entry entry = (Map.Entry) itset;
System.out.println(entry.getKey()+"-"+entry.getValue());
}
}
//输出集合对象
System.out.println(map);
}
}
六、Collection与Map区别
Collection:存储的数据时不唯一、无序的对象
List:存储的数据是不唯一、有序(输入顺序与输出顺序一致)的对象
Set:存储的数据是唯一( 元素不能重复)、无序的对象
HashMap:无序;key唯一,value不唯一
HashXxx:底层借助了“哈希表”的数据结构;默认不支持排序
TreeXxx:底层借助了“红黑树”的数据结构;默认支持排序
Collection与Map虽然底层有联系,但是他们在接口层面没有继承实现关系
Collection:单值集合
Map:”键值对“集合(key和value之间一一对应)
删除:Collection(List、Set):删除返回值为Boolean;Map:删除返回值为元素
遍历:(1)for循环[普通for(set、map不能使用),增强for](2)迭代器
Map遍历:将双值集合转为单值集合,
七、泛型
1、作用
(1)数据安全
(2)防止类型转换时出错
2、泛型概述和好处
泛型概述
是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型,参数类型可以用在类、方法和接口中,分别被称为泛型类、泛型方法、泛型接口
泛型定义格式
<类型>:指定一种类型的格式。这里的类型可以看成是形参,不能用基本数据类型,只能使对象
<类型1,类型2…>:指定多种类型的格式,多种类型之间用逗号隔开。这里的类型可以看成是形参
将来具体调用时候给定的类型可以看成是实参,并且实参的类型只能是引用数据类型
泛型的好处
把运行时期的问题提前到了编译期间
避免了强制类型转换
包装类
将8 个基本类型,包装成了8个对象。这8 个对象类型就成为包装类
自动装箱:int--->Integer(值不在[-128,127]之间的,比较地址);
自动拆箱:Integer-->int;
3、泛型类
定义格式
修饰符 class 类名<类型> { } public class Generic <String>{}
4、泛型方法
定义格式
修饰符 <类型> 返回值类型 方法名(类型 变量名) { } public class Generic { public <String> void show(String str) { System.out.println(t); } }
5、泛型接口
修饰符 interface 接口名<类型> { }
public interface Generic<String> { }
6、类型通配符
类型通配符的作用
为了表示各种泛型List的父类,可以使用类型通配符
类型通配符的分类
类型通配符:<?>
List<?>:表示元素类型未知的List,它的元素可以匹配任何的类型
这种带通配符的List仅表示它是各种泛型List的父类,并不能把元素添加到其中
类型通配符上限:<? extends 类型>
List<? extends Number>:它表示的类型是Number或者其子类型
类型通配符下限:<? super 类型>
List<? super Number>:它表示的类型是Number或者其父类型
7、可变参数
可变参数介绍
可变参数又称参数个数可变,用作方法的形参出现,那么方法参数个数就是可变的了
可变参数定义格式
修饰符 返回值类型 方法名(数据类型… 变量名) { } public static int sum(int... a) { int sum = 0; for(int i : a) { sum += i; } return sum; } System.out.println(sum(10, 20)); System.out.println(sum(10, 20, 30));
可变参数的注意事项
这里的变量其实是一个数组
如果一个方法有多个参数,包含可变参数,可变参数要放在最后
8、可变参数的使用
Arrays工具类中有一个静态方法:
public static <T> List<T> asList(T... a):返回由指定数组支持的固定大小的列表
返回的集合不能做增删操作,可以做修改操作
List接口中有一个静态方法:
public static <E> List<E> of(E... elements):返回包含任意数量元素的不可变列表
返回的集合不能做增删改操作
Set接口中有一个静态方法:
public static <E> Set<E> of(E... elements) :返回一个包含任意数量元素的不可变集合
在给元素的时候,不能给重复的元素
返回的集合不能做增删操作,没有修改的方法
八、集合工具类
1、集合工具类Collections(处理集合)
Collections概述和使用
Collections类的作用
是针对集合操作的工具类
Collections类常用方法
方法名 说明 public static void sort(List<T> list) 将指定的列表按升序排序 public static void reverse(List<?> list) 反转指定列表中元素的顺序 public static void shuffle(List<?> list) 使用默认的随机源随机排列指定的列表
//创建集合对象
List<Integer> list = new ArrayList<Integer>();
//添加元素
list.add(30);
list.add(20);
//将指定的列表按升序排序
Collections.sort(list);
//反转指定列表中元素的顺序
Collections.reverse(list);
//使用默认的随机源随机排列指定的列表
Collections.shuffle(list);
//二分查找(使用前保证集合元素是自然有序的)返回元素位置
Collections.sort(list);
Collections.binarySearch(list)
//打乱已有顺序
Collections.shuffle();
//将位置2与位置3的元素交换位置
Collections.swap(list,2,3)
//将集合中所有20替换为100
Collections.replaceAll(list,20,100)
//将集合全部用00填充
Collections.fill(list,00)
}
2、数据工具类Arrays 比如:Arrays.sort(数组)
方法与Collestions差不多
补充:
2、比较器
Collections.sort(list) //能够识别一些自然顺序:数字大小,字母表
如果集合中的元素是用户自定义对象则需要自定义比较器:Compareble、Comparetor
Compareble:内部比较器
将比较对象实现comparable接口,重写compareTo()方法
注:Person是个自定义类
public int compareTo (Object o){
Person inputPerson=(Person) o;
//根据学号,降序
int result= this.id>inputPerson.id ? 1 :(this.id==inputPerson.id ? 0: -1);
//如果学号相同根据姓名升序/降序(在this前面加‘ - ’)
if(result==0){
result=this.name.compareTo(inputPerson.name);
}
return result;
}
Comparator:外部比较器,无侵入性,不需要修改原有代码
思路:先写一个类实现Comparator接口;重写compare方法
使用方法:Collections.sort(person,new Mycompare());
3、equal()方法和hashcode()的重写
@Override
public boolean equals(Object o) {
// 首先判断传进来的o是否是调用equals方法对象的this本身,提高判断效率
if (o==this){return true;}
// 判断传进来的o是否是null,提高判断效率
if (o==null){return false;}
判断传进来的o是否是对象,防止出现类型转换的异常
if (o instanceof Book){
Book book =(Book) o;
boolean flag=this.title.equals(book.title)&&this.price==book.price&&this.author.equals(book.author);
return flag;
}
// 如果没有走类型判断语句说明两个比较的对象它们的类型都不一样,结果就是false了
return false;
}
@Override
public int hashCode() {
// result = 31 *result + (对象 !=null ?对象.hashCode() : 0);
// result = 31 *result + 基本数值类型;(int)
// result=31*result+(int)(Double.doubleToLongBits(x));强制转换为int类型
// result = 31 *result + (布尔变量?1:0);
int result=title.hashCode();
result = 31*result+author.hashCode();
result=31*result+(int)(Double.doubleToLongBits(price));
return result;
}
4、并发修改异常
出现的原因
迭代器遍历的过程中,通过集合对象修改了集合中的元素,造成了迭代器获取元素中判断预期修改值和实际修改值不一致,则会出现:ConcurrentModificationException
解决的方案
用for循环遍历,然后用集合对象做对应的操作即可
5、列表迭代器
ListIterator介绍
通过List集合的listIterator()方法得到,所以说它是List集合特有的迭代器
用于允许程序员沿任一方向遍历的列表迭代器,在迭代期间修改列表,并获取列表中迭代器的当前位置
6、增强for循环
定义格式
for(元素数据类型 变量名 : 数组/集合对象名) { 循环体; } for(String s : list) { if(s.equals("world")) { list.add("javaee"); //ConcurrentModificationException } }