面向接口编程:
接口类型变量 = new 实现类();
List list = new ArrayList();
List实现类特点和性能分析:
三者共同的特点共同遵循的规范:
1)允许元素重复;
2)记录元素的先后添加顺序;
Vector类:底层采用数组结构算法,方法都使用了synchronized修饰,线程安全,但是性能相对于ArrayList较低。
Arraylist类:底层采用数组结构算法,方法没有使用synchronized修饰线程不安全,性能相对于vector较高。
ArrayList现在几乎已经取代了Vector的江湖地位。
了保证ArrayList的线程安全,List list = Collections.synchronizedList(new ArrayList(..);
LinkedList类:底层采用双向链表结构算法方法没有使用synchronized修饰,线程不安全;
数组结构算法和双向链表结构算法的性能问题:
数组结构算法:插入和删除操作速度低,查询和更改较快;
链表结构算法:插入和删除操作速度快,查询和更改较慢;
使用的选择:
Vector类不用不用,即使要用选ArrayList类。
如果删除和插入操作频繁应该选择LinkedList类。
如果查询操作频繁,应该使用ArrayList类。
在开发中使用ArrayList较多,根据具体的需求环境来做选择。
集合的迭代操作
✎
集合的迭代操作:把集合做的元素一个一个的遍历取出来。
package com_520it_day02_iterator;
import java.util.ArrayList;
import java.util.List;
//集合元素的迭代/遍历操作
public class IteratorDemo {
public static void main(String[] args) {
List list = new ArrayList();
list.add("A");
list.add("B");
list.add("C");
list.add("D");
//方式1:for循环
for (int index = 0; index < list.size(); index++) {
Object ele = list.get(index);//取出指定索引位置的元素
System.out.println(ele);
}
System.out.println("---------------------");
//方式2:for-each增强for循环
/*
for(类型 变量 :数组名/Iterable的实例){
//TODO
}
*/
for (Object ele : list) {
System.out.println(ele);
}
}
}
迭代器对象:Iterator:迭代器对象,只能从上往下迭代;
boolean hasNext(): 判断当前指针后是否有下一个元素;
Object next():获取指针的下一个元素,并且移动指针。
ListIterator:是Iterator接口的子接口,支持双向迭代,从上往下
迭代从下往上迭代;
//方式3:使用迭代器Iterator
Iterator it = list.iterator();
while (it.hasNext()) {
Object ele = it.next();
}
//方式4:使用for循环来操作迭代器Iterator
for (Iterator it2 = list.iterator(); it2.hasNext();) {
System.out.println(it2.next());
}
Enumeration:古老的选代器对象现在已经被lterator取代了。适用于古老的Vector类。
package com_520it_day02_iterator;
import java.util.Enumeration;
import java.util.Vector;
public class EnumerrationDemo {
public static void main(String[] args) {
Vector v = new Vector();
v.add("A");
v.add("B");
v.add("C");
v.add("D");
//迭代操作
for (Enumeration en = v.elements(); en.hasMoreElements();) {
Object ele = en.nextElement();
System.out.println(ele);
}
}
}
深入分析for- each和迭代器
1)for-each可以操作数组:
底层依然采用for循环+索引来获取数组元素。
2)for-each可以操作Iterable的实例:底层其实采用的Iterator(迭代器),直接使用for-each迭代数组和集合元素即可,更简单。
for(类型 变量 :数组名/Iterable的实例){
//TODO
}
当需要边迭代边删除指定的集合元素时:此时只能使用迭代器。而且只能使用迭代器对象的remove方法。
当使用迭代的时候,在当前线程A中,会单独创建一个新的线程B。A线程负责继续迭代B线程负责去删除。
B线程每次都会去检查和A线程中的元素是否个数相同,如果不是,报错:
ConcurrentModificationException。
在迭代集合的时候边迭代边删除是非常常用的操作:
如何解决并发修改异常呢?
不要使用集合对象的删除方法。在collection接口中存在删除指定元素的方法:boolean remove(Object ele); 该方法只能从集合中删除元素,不能把迭代器中指定的元素也删除。
我们应该使用Iterator中的remove方法。该方法会从两个线程中同时移除被删除的元素,保证了两个线程的同步。
泛型操作
✎
为什么需要使用泛型:
1)存储任意类型(Object)的数据在集合中,但是取出来都是Object类型的,此时就得强转。
2)约束存储到集合中的元素必须是相同的数据类型(相同的数据类型才能做比较)比如TreeSet类;
3)设计一个点(Point)类,来封装坐标位置,要求坐标位置支持String类型、Integer类型、Double类型。非常不优雅的设计,如下图(重复定义)
泛型(GenericType),从Java5开始支持的新的语法:
什么是泛型:
1)广泛通用的类型;
2)代码模板中类型不确定,谁调用该段代码,谁指明类型是什么。
泛型类:直接在类/接口上定义的泛型。
使用泛型:保证前后类型相同
List<String> list = new ArrayList<String>();//该List集合中只能存储String类型的元素.
因为前后类型相同,所以从Java7开始,推出出泛型的菱形语法<>。
List<String> list = new ArrayList<>();
泛型不存在继承的关系(错误如下):
List<Object> list = new ArrayList<String>();//错误的
从此以后,使用集合都得使用泛型来约束该集合中元素的类型。
通过反编译发现:泛型其实也是语法糖,底层依然没有泛型,而且依然使用强转。
泛型方法:在方法上声明泛型。
情况1 )泛型类中的泛型只能适用于非静态方法,如果需要给静态方法设置泛型,此时使用泛型方法;
情况2)泛型类中的泛型应该适用于整个类中多个方法,有时候只对某一个方法设置泛型即可。
一般的,把自定义的泛型作为该方法的返回类型才有意义,而且此时的泛型必须是由参数设置传进来的。如果没有参数来设置泛型的具体类型,此时的方法一般返回设计为Object即可。
泛型的通配符和上限和下限:
泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用?表示未知通配符。此时只能方法中接受传入的数据,不能往该集合中存储数据。
泛型的上限和下限:用来限定元素的类型,必须是X类的子类或者相同,X的父类或相同。
泛型擦除和转换:
泛型的擦除:
1)泛型编译之后就消失了(泛型自动擦除);
2)当把带有泛型的集合赋给不带泛型的集合,此时泛型被擦除(手动擦除)。
堆污染:
单一个方法既使用泛型的时候也使用可变参数,此时容易导致堆污染问题。如:在Arrays类中的asList方法:public static <T> List<T> asList(T... arr).
package com_520it_day02_generictype;
import java.util.List;
import java.util.ArrayList;
public class GenericTypeDemo2 {
public static void main(String[] args) {
//带有Integer泛型
List<Integer> list1 = new ArrayList<>();
list1.add(123);
//list1.add("ABC");//此时报错
//不带有泛型
List list2 = list1;//此时泛型被檫除
list2.add("ABC");//验证无错
//带有String泛型
List<String> list3 = null;
list3 = list2;//此时只是绕开立刻编译器的检查,有问题。这就是堆污染
//报错:java.lang.Integer cannot be cast to java.lang.String
String num = list3.get(0);//取出123 等价于:String String = 123;报错
}
}
java培训:http://www.baizhiedu.com/java2019