泛型部分需要好好加强下
推荐书籍
JVM《深入理解JAVA虚拟机》周志明
架构《大型网站架构技术》李智慧
算法《算法导论》
线程《Java并发编程实战》
设计模式《大话23种设计模式》
Java基础《疯狂Java讲义》
1.集合的介绍以及和数组的区别
集合是一个容器这个容器可以存放很多数据
集合和数组的区别:
1.数组可以存放任何类型的数据
集合只能存放引用类型的数据
2.数组长度不变
集合长度可变
ArrayList是一个集合,长度可变,ArrayList集合内部是在使用一个数组保存数据
2.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() : 把集合中的元素,存储到数组中。
3.集合的遍历
我们之前使用for循环结合索引的方式去遍历结合,但是这种方式并不适用于所有的集合,因为有些集合是没有索引的
有一种通用的集合的便利方式,适用于所有的集合,这种遍历的方式叫做迭代器遍历
迭代器就是遍历结合的工具,内部有一个光标,最开始指向了集合的最开头的元素
如何获取集合的迭代器?
调用Collection中的iterator方法即可
IteratorM<E> iterator(): 获取到集合的迭代器对象
Iteratior表示一个迭代器,如果要使用迭代器遍历,还需要受窘迭代器中的一些方法
boolean hasNext() 判断迭代器当且光标位置手还有元素可以获取。如果还有元素可以获取,那么返回true
E next(): 获取当前光标位置的元素,把光标向后移动。
遍历步骤:
1.获取这个集合的迭代器对象。
集合.iterator();
2.使用迭代器的hasNext方法判断是否还有元素可以获取。
迭代器.hasNext();
3.如果有元素可以获取,那么就调用next方法获取元素
迭代器.next();
使用while遍历结合
while(iterator.hasnext()){
}
注意:
并发修改异常
当我们使用迭代器遍历集合的时候,同时使用集合的方法对相机和中的元素进行添加或者删除将来就会引发并发修改异常
在JDK5的时候多了一个新特性,叫做增强for循环(foreach),可以对集合或者数组进行遍历
格式:
for(数据类型 变量名: 容器){
//循环体
}
格式解释:
数据类型:要遍历的容器中保存的是什么类型的数据,这个数据类型就写什么。
变量名:该变量表示容器中的每一个元素
容器:要遍历的容器
增强for是一种语法糖,语法糖指的是本质没有变,只不过写法更加的优雅,简洁
增强for本质还是普通的for循环
增强for优缺点:
优点:省去了对索引的操作,语法简洁
缺点:不能操作索引。如果循环过程中需要操作索引,则还需要使用普通for循环
4.泛型
反应就是一种未知的,不确定的数据类型。
比如:ArrayList<E>,E就是泛型(未知的,不确定的数据类型)
在我们使用这个类的时候才可以确定这个E所表示的类型
在Java中泛型可以省略,如果省略泛型,可以看成泛型是Object
泛型的好处:
1.省略了强转的代码
2.将运行时的问题提前到了编译时期
泛型擦除
Java中的泛型都是伪泛型
泛型只在源代码阶段有效,一旦编译,泛型就会消失
泛型指的是一种未知的,不确定的数据类型
如果在定义类的时候类名后面加上<T>,那么这个类就变成了泛型类,<>中的字母可以是任何字母
而且表示这个类中定义了一个,不确定的数据类型T,这个T表示的是数据类型必须等到使用它的时候才知道它的数据类型
使用已定义好一个泛型的类,创建对象时,必须要明确泛型的类型
如果想要所限泛型的使用和范围,延后泛型的确认时间,可以使用泛型方法
在方法中定义的泛型,只能在方法中使用
在方法中定义的泛型(未知的数据类型)所表示的数据类型,必须等到调用方法的时候才能确定
泛型方法的定义格式:
修饰符<泛型> 返回值类型 方法名(参数列表){
方法体;
}
小结:
如果在类上面定义泛型,这个就是泛型类。 在类上面定义的泛型,需要等到使用这个类的时候才能确定这个泛型表示的是具体的什么类型。
如果在方法上面定义泛型,这个就是泛型方法。 在方法上面定义的泛型,需要的等到调用方法的时候才能确定这个泛型表示的是具体的什么类型。
如果在定义接口的时候,在接口名后面加上<T>,那么这个接口就是一个泛型接口
这个T表示在接口中定义了一种未知的,不确定的数据类型T
泛型接口的使用:
1.实现类实现接口的时候直接明确接口中的泛型的数据类型
直接在接口名后面加上<泛型>
2.实现类实现接口的时候不确定接口的泛型的数据类型,等到实现的时候再明确泛型的数据类型
只有在常见类或者接口的时候,在当前的类名或者接口名的寿面写的尖括号<>才是定义泛型。
泛型之间并没有继承关系
例如:
ArrayList<Object>并不是ArrayList<String>的父类
如果想要泛型可以接受(匹配)任何类型,那么我们可以使用泛型通配符<?>
?表示泛型通配符,可以匹配任何类型的泛型
泛型通配符只能被动接受(匹配),不能主动使用
泛型的限定:
可以对泛型通配符<?>的范围进行一个限制
<?extends A>: 泛型要么是A类,要么是A类的子类 上限(最高到A类)
<?super A>: 泛型要么是A类,要么是A类的父类 下限(最低到A类)
泛型的作用:
主要用于代码的优化以及重构