集合
单例集合中:
学习Collection集合
基本功能:
添加功能:
boolean add(Object e) :将任何数据类型添加到集合中
删除功能:
void clear():暴力删除
boolean remove(Object o):移出指定的元素
判断功能
boolean contains(Object o):判断是否包含指定的元素
boolean isEmpty():判断集合是否为空,如果为空,则返回 true;
转换功能:
Object[] toArray():将集合转换成对象数组
Iterator iterator():Collection集合的迭代器(集合的遍历方式)
Collection高级功能
boolean addAll(Collection c):添加所有
boolean containsAll(Collection c):包含所有(包含一个算包含还是包含所有?)
包含所有元素才算包含,返回true
boolean removeAll(Collection c):删除所有 (删除一个还是删除所有算是删除?)
只要集合中有一个元素被包含,将这个元素从c1删除掉,则返回true!
boolean retainAll(Collection c):一个集合对另一个集合取交集 (返回值boolean的含义是什么)
A集合对B集合取交集,将交集的元素保存到A集合,boolean表达的是A集合是否发生变化
如果A集合没有变化的,返回结果false;如果A集合有变化,则返回true!
迭代器:Iterator(集合的专有遍历方式)
Collection集合的高级功能:
Object[] toArray()
Iterator iterator():Collection集合的专有遍历方式
iterator()的返回值是接口:需要返回的是该接口的子实现类对象!
Iterator:存在一个方法
Object next():获取下一个元素
boolean hasNext():判断当前迭代器中是否有下一个可以遍历元素,
如果存在,则返回true;
迭代器的注意事项:
迭代器的注意事项:
1)Object next()获取当前集合的元素(),不能使用多次,使用一次即可,
获取所有元素信息
2)能使用for循环,不推荐(因为以后集合中元素可能不知道个数,使用while循环)
什么是泛型
什么是泛型
格式
<数据类型:引用数据类型>
集合为了迎合数组的特点,在创建数组的时候,将类型定义了,来保证集合中的元素类型一致的!
泛型的特点:
将集合的类型在创建的时候就明确,保证集合操作的安全性!
好处:
1)避免了强制类型转换
2)将运行时期异常提前到了编译时期
3)解决了黄色警告线问题
4)提高了程序的安全性!
泛型的应用
泛型可以应用在哪些地方
泛型在集合中使用居多,可以定义类上,可以放在方法上,也可以放在接口上!
没有加入泛型之前,程序存在安全隐患,出现类型不匹配:ClassCastException:属于运行时期异常!
1)普通使用
2)将泛型先定义在类上,方法形式参和泛型类型保持一致
3)将泛型定义在方法上
4)将泛型定义在接口上
泛型的高级通配符
泛型的高级通配符
<?> 当前Object类型/任意Java类型(自定义/jdk提供...)
<? extends E>:向下限定:E类型以及它的子类
<? super E>:向上限定:E类型以及它的父类
1.List集合
List集合 extends Collection
有序的集合,可以允许元素重复!
有序性:存储和取出一致
使用List集合存储字符串并遍历
两种方式:
1)Object[] toArray()
2)Collection集合的Iterator
List集合的特有功能
List集合的特有功能:
添加功能
void add(int index,Object element):在指定位置处添加一个新的元素
删除功能
Object remove(int index):删除角标对应的元素
获取功能
Object get(int index) :获取指定位置处的元素
int size():获取集合的元素数
Object set(int index,Object element):在指定位置处使用当前元素element元素替换
ListIterator<E> listIterator():List集合的专有遍历方式 :列表迭代器
listIterator():List集合的专有遍历方式 :列表迭代器
ListIterator<E> listIterator():List集合的专有遍历方式 :列表迭代器
ListIterator:列表迭代器
ListIterator<E> listIterator()这个方法底层实现:是通过ArrayList里面的成员内部类
ListItr extends Itr :实现的
正向遍历
boolean hasNext():判断是否有下一个元素
Object next() :获取下一个元素
逆向遍历
boolean hasPrevious():判断是否有上一个元素
Object previous():获取前一个元素
逆向遍历:前提条件:先有正向遍历
List集合的遍历方式
List集合的遍历方式:
1)Collection集合的方法 Object[] toArray
2)Collection集合的迭代器Iterator iterator()
3)size()+Object get(int index):普通for循环
4)列表迭代器:ListIteraotr listiterator()
5)增强for循环
并发修改
java.util.ConcurrentModificationException:并发修改
当迭代器遍历元素的时候,不能使用集合添加元素!(当前集合中添加一个新的元素,迭代器不知道!)
解决方案:
1)要么使用迭代器遍历元素,使用迭代器添加元素!
2)要么集合遍历元素,使用集合添加元素
并发:指的是在一个时间点上同时发生!
并行:指的是在一个时间段内同时发生!
List集合的三个子实现类的特点
List三个子实现类的特点:
ArrayList:
底层数据结构是可变数组结构: 查询快,增删慢
ArrayList底层可变数组:
ArrayList(int initialCapacity) :通过初始化容量构造ArrayList集合
默认容量大小:capacity:10个
ArrayList()---->通过初试容量大小判断是否构造一个新Object[] 数组对象
结论:它的扩容机制 ---1.5倍扩容
线程角度:
线程不安全的类----不同步的----执行效率高!
单线程程序中,通常没有告诉使用什么集合的时候,优先采用的是ArrayList集合!
Vector:
底层数据数组结构(对象数组) ,查询快,增删慢
线程角度:
线程安全的类 ---->同步的----->执行效率低
多线程程序中要考虑安全问题,使用Vector
LinkedList:
底层数据结构:链接列表实现(链表)查询慢,增删快
线程角度:
线程不安全-----不同步---->执行效率高
特有功能:
可以模拟栈结构的:先进后出!
线程安全的类
StringBuffer/Vector
JDK5之后提供了特性:
JDK5之后提供了特性:
<引用类型>泛型,静态导入,增强for,可变参数,自动拆装箱
增强for的格式:
for(数据类型 变量名 : 数组对象/集合对象(使用最多)){
输出变量名即可
}
作用:是替代迭代器使用,简化遍历集合的书写格式!
注意事项:
1)增强for主要用在集合中,数组一般使用的时候普通for
2)前提条件:
要使用增强for循环的话,必须保证该集合不能为null,否则就会出现空指针
NullPointerException
解决方案:
针对该对象非空判断即可!
ArrayList集合
ArrayList集合实现了List接口!
可以存储重复元素,存储和取出一致(有序的)!
ArrayList:单线程程序中考虑执行效率,优先采用!
在一些嵌套中使用
HashMap<String,ArrayList<String>> :Map集合嵌套ArrayList
ArrayList<ArrayList<Student>> :ArrayList嵌套ArrayList
Vector集合:
Vector集合:
底层数组结构:查询快,增删慢
线程安全的---->同步的---->执行效率低!
public boolean add(Object e):传统添加元素的方法
特有功能:
public void add(int index, E element):插入元素
public Enumeration<Object> elements() --- 相当于:Iterator iterator()
该接口有两个方法
boolean hasMoreElements():判断是否有下一个元素-----> 相当于:boolean hasNext()
Object nextElement():获取一个元素 -----> 相当于:next()
public Object elementAt(int index):通过角标获取指定的元素---->相当于:Object get(int index)
elementAt()+size() :vector的普通for遍历方式
Enumeration和Iterator功能是重复的
场景:
IO流:合并流 SequenceInputStream 可以将多个文件内容读出来复制到指定文件中!
操作的输入流!
LinkedList集合
LinkedList集合的特点:
底层数据结构是链接列表,查询慢,增删快
线程不安全的---不同的---->执行效率高!
应用场景:
网站中 记录用户浏览过商品足迹 (Web技术:Cookie/Session)
特有功能
添加
public void addFirst(Object e):将该元素添加到列表的开头!
public void addLast(Object e):将该元素添加到列表的末尾!
删除
public Object removeFirst():删除列表第一个
public Object removeLast():删除列表最后一个
获取
public Object getFirst():获取第一个
public Object getLast() :获取第二个
进栈和弹栈
public Object pop():此列表所表示的堆栈处弹出一个元素
public void push(Object e):将元素推入此列表所表示的堆栈
2.Set集合
Set集合的特点:
元素是不重复的,无序的!(存储和取出不一致,取决于底层HashMap实例)
子实现类
HashSet
TreeSet
HashSet集合
使用HashSet集合存储自定义对象并遍历
HashSet<Student>
HashSet集合没有去重
底层依赖于HashCode和equals()方法
使用HashSet:底层hash表结构 来保证元素的唯一性!
存储自定义对象,必须重写hashcode()和equals()
TreeSet集合
TreeSet集合:
本质基于TreeMap的底层实现(红黑树结构---->自平衡"的二叉树结构")
有两种排序方式:
自然排序
选择器排序
取决于创建当前Set集合对象的时候的构造方法
public TreeSet():默认的自然顺序排序
TreeSet<Integer>
由于TreeSet属于Set集合(本身保证元素唯一,不重复的元素!),还可以将元素按照自然顺序排序
创建TreeSet集合
方式1:直接给了创建了接口子实现类
TreeSet<Student> ts = new TreeSet<Student>(new MyComparator()) ;
形式参数是一个接口类型,需要传递该接口子实现类对象
方式2:形参参数如果接口:传入接口的匿名内部类(本质:接口的子实现类)
匿名内部类(推荐的方式)
匿名内部类的格式:
new 类名/接口名(){
重写抽象类中或者接口中的抽象方法...
};
3.Map集合
Map集合:
java.util.Map<K,V>:接口
Java提供了集合:双列集合
键:K 学号:String "班级+学号id" 键的特点:必须唯一的!
键值:V 学生Student
Map集合的特点: 一个值对元素(一个键对应一个值,值是可以重复,但是键必须唯一)
只针对键有效,跟值无关! (看成是:夫妻对)
Map和Collection集合的区别
Map和Collection集合的区别?
Map<K key,V value>集合:双列集合,键映射到值的对象 ,键必须保证唯一,可以看成是一个(夫妻对)
遍历方式和Collection集合遍历方式不同
Collection<E>集合:
单列集合:只能存储一种引用类型,里面的set集合依赖于Map集合的实现 (理解为:光棍)
HashSet---->HashMap里面put方法
TreeSet---->TreeMap里面的put方法
Map集合的功能
Map集合的功能:
添加功能
V put(K key, V value) :添加一个键值对元素
问题:返回值是什么意思
如果当前键是一次存储的时候,返回的结果null
如果键是不是第一次存储,后面重复,将当前对应的值把以前的值覆盖掉并保存下来,返回以前的值!
刪除功能:
V remove(Object key):刪除指定的键,返回的是跟键关联的值,如果没有映射关系,则返回null
void clear():删除全部的键以及值
判断功能
boolean containsKey(Object key):是否包含指定的键
boolean containsValue(Object value):是否包含指定的值
boolean isEmpty():判断Map集合是否为空
高级功能
高级功能:
方式1:(推荐的方式:Map常用的方式)
Set<K> keySet():获取所有的键的集合
V get(Object key):通过键获取对应的值
遍历Map集合
方式1:Set<K> keySet():获取所有的键的集合
Set<String> set = map.keySet() ;
for(String key : set) {
V get(Object key):通过键获取对应的值
String value = map.get(key) ;
System.out.println(key+"="+value);
}
方式2遍历
Set<Map.Entry<K,V>> entrySet():获取当前Map集合中所有的键值对对象
K getKey() :通过键值对对象获取键
V getValue():通过键值对对象获取值
获取所有的键值对对象
Set<Map.Entry<String, String>> entrySet = map.entrySet() ;
for(Map.Entry<String, String> entry :entrySet) {
String key = entry.getKey() ;
String value = entry.getValue() ;
System.out.println(key+"="+value);
}
HashMap集合
HashMap<K,V>是Map集合的子实现类,里面哈希表结构,保证(键唯一)
Map集合只只针对键有效
HashMap<Integer,String>键:Integer
HashMap<String,Student> :键:String
HashMap<Student,String>:键是自定义对象
HashMap<String,Student> :键:String,值:Student
键:学号
值:学生信息
自定义的对象存储在值的位置,是可以重复的!,如果是在键位置,不能重复!
HashMap<Student,String>:键是自定义对象
键:学生:自定义对象
值:String:朝代
对于Map存储的键如果是自定义对象:
该自定义对象的所在类必须重写Object:equals()和hashCode()
会依赖于HashMap的put方法
hash()---->依赖于hashCode():算出每一个对象哈希码值一样
putValue()---->equals()方法:哈希码值一样,还有比较每一个成员信息是否相同!
TreeMap集合
TreeMap:红黑树结构
构造方法:
public TreeMap():默认的自然顺序排序
public TreeMap(Comparator<? super K> comparator):是一种比较器排序(推荐)
TreeMap<Student,String> / TreeSet<Studdent>: 一定要有条件进行排序!
按照主要条件:学生的年龄从小到进行排序!
面试题
面试题:
TreeSet集合存储自定义类型,什么情况下自然排序(Comparable),什么情况下是选择器排序(Comparator)?
执行无参构造方法:TreeSet<Student>():无参构造----是自然排序:
要求当前自定义类型需要实现Comparable接口,重写comparesTo方法
执行有参构造方法:TreeSet<Student>(Comparator<Student> com):
方式1:自定义一个类实现Comparator接口中 的compare(T t1,T t2)方法
方式2:通过接口匿名内部类实现(需要啥实现排序方式)
例:
@Override
public int compare(Student s1, Student s2) {
int num = s1.getAge() - s2.getAge() ;
int num2 = (num==0) ? (s1.getName().compareTo(s2.getName())): num ;
return num2;
}
可以针对Collections集合进行操作的工具类
Collections:java.util.Collections 类
可以针对Collection集合进行操作的工具类!
public static <T> int binarySearch(List<?> list,T key):针对集合的二分查询方法:
查询key在集合中出现的索引值. 集合:必须是有序的!
public static <T> T max(Collection<? extends T> list):获取集合中最大值
public static <T> T min(Collection<? extends T> list):获取集合中最小值
public static <T> void sort(List<T> list):针对List集合进行排序:升序排序
public static <T> void sort(List<T> list,Comparator<T> com):比较器排序
public static void shuffle(List<?> list):针对List集合的元素进行随机置换