java 集合类之间的继承关系
Java的集合类主要由两个接口派生而出:Collection和Map,Collection和Map是Java集合框架的根接口。代表了两种不同的数据结构:集合和映射表。
图中,ArrayList,HashSet,LinkedList,TreeSet是我们经常会有用到的已实现的集合类。
Map实现类用于保存具有映射关系的数据。Map保存的每项数据都是key-value对,也就是由key和value两个值组成。Map里的key是不可重复的,key用户标识集合里的每项数据。
迭代器的作用
由于Java中数据容器众多,而对数据容器的操作在很多时候都具有极大的共性,于是Java采用了迭代器为各种容器提供公共的操作接口
解耦效果:使用迭代器iterator可以使对容器的遍历操作完全与其底层相隔离,可以到达极好的解耦效果
iterator方法返回一个实现了Iterator接口的对象,作用是依次访问集合中的元素,Iterator
1 | boolean hasNext(); # 如果任有元素可以迭代,则返回true. |
通过多次调用next()方法可遍历集合中的所有元素,需要注意的是需要在调用next()之前调用hasNext()方法,并在hasNext()返回true的时候才可以调用next().
1 | public static void main(String[] args) |
遍历集合时删除特定元素一定要用Iterator的remove,别用集合自带的remove。会报错:
java.util.ConcurrentModificationException
在集合内部维护一个字段modCount用于记录集合被修改的次数,每当集合内部结构发生变化(add,remove,set)时,modCount+1。
在迭代器内部也维护一个字段expectedModCount,同样记录当前集合修改的次数,初始化为集合的modCount值。当我们在调用Iterator进行遍历操作时,如果有其他线程修改list会出现modCount!=expectedModCount的情况,就会报并发修改异常java.util.ConcurrentModificationException
集合的排序
java集合的工具类Collections中提供了两种排序的方法,分别是:
Collections.sort(List list)
Collections.sort(List list,Comparator c)
第一种称为自然排序,参与排序的对象需实现comparable接口,缺点会入侵代码
第二种叫定制排序,或自定义排序,需编写匿名内部类,先new一个Comparator接口的比较器对象,优点不用修改排序对象代码,例子:
1 | Collections.sort(ordered, new Comparator<Student>() { |
java8函数式排序
1 | //根据学生身高排序 |
泛型
泛型类
1 | class Demo<T>{ |
泛型类的方法和泛型方法区别:
- 一个是在实例化对象才确认下来的 【泛型类的方法】
- 一个是在方法调用时确认下来的 【泛型方法】
普通泛型类的方法
1 | // 虽然方法中使用了泛型,但这并不是泛型方法 |
加static会编译错误
泛型方法
可以加static
1 | // 这个<T>修饰的方法才是真的泛型方法 |
泛型方法总结
- 泛型类,是在 【实例化类】 的时候指明泛型的具体类型;
- 泛型方法,是在调用方法的时候指明泛型的具体类型 ,注意跟类实例化没关系了。
- 泛型方法可以加static,普通的泛型类的方法是不可以的
使用泛型方法好处
- 因为泛型方法类型可以灵活的传入参数类型,不像泛型类的方法实例化后就固定掉了。
- 每次调用泛型方法入参类型都可以灵活的变化,可以看我的例子
- 泛型方法支持static
spring注解、事务传播机制
7种事务的传播机制(可通过spring配置或注解来设置)
- REQUIRED(默认):支持使用当前事务,如果当前事务不存在,创建一个新事务。
- SUPPORTS:支持使用当前事务,如果当前事务不存在,则不使用事务。
- MANDATORY:中文翻译为强制,支持使用当前事务,如果当前事务不存在,则抛出Exception。
- REQUIRES_NEW:创建一个新事务,如果当前事务存在,把当前事务挂起。
- NOT_SUPPORTED:无事务执行,如果当前事务存在,把当前事务挂起。
- NEVER:无事务执行,如果当前有事务则抛出Exception。
- NESTED:嵌套事务,如果当前事务存在,那么在嵌套的事务中执行。如果当前事务不存在,则表现跟REQUIRED一样。
事务注解失效的例子
1 |
|
解决方案:把事务代码下沉,用一个类去单独处理
1 | public class WePageManagerServiceImpl implements WePageManagerService { |
@Transactional失效原因分析:自身调用导致失败
在应用系统调用声明@Transactional 的目标方法时,Spring Framework 默认使用 AOP 代理,在代码运行时生成一个代理对象,再由这个代理对象来统一管理,当在Service实现类直接调用内部方法时,其本质是通过this对象来调用的方法,而不是代理对象,因为会出现事务失效的情况
总结一句话,自身调用没有经过 Spring 的代理类
事务失效3种常见原因
- 自身调用(面试最爱问啦)
- 异常被吃
- 异常抛出类型