目录
包装类
装箱,拆箱
??装箱的比较
?List接口
ArrayList集合
Collection集合的遍历
Iterator遍历集合
?迭代器的删除异常
ArrayList集合的ConcurrentModificationException异常
?异常出现的原因
单线程的解决方法---调用迭代器的方法
多线程的解决方法---使用CopyOnWriteArrayList
for-each遍历
for循环遍历
包装类
八个基本类型分别对应各自的包装类,包装类包括了对于基本类型的操作
例如int的包装类Integer
public static void main(String[] args) {
int s = Integer.valueOf(3);
//等价于
int a = 3;
System.out.println(s);
System.out.println(a);
int str = Integer.valueOf("123");//将字符串转化为数字
System.out.println(str);
}
装箱,拆箱
装箱---将普通类型转化为包装类类型
拆箱---将包装类类型转化为普通类型
public static void main(String[] args) {
Integer s=123;//装箱
int b=s;//拆箱
Integer str=Integer.valueOf(123);//显示装箱
int a=str.intValue();//显示拆箱
}
隐式的装箱和拆箱都是通过调用方法来实现的?
?装箱的比较
public static void main(String[] args) {
Integer a=13;
Integer b=13;
System.out.println(a==b);
Integer c=139;
Integer d=139;
System.out.println(c==d);
}
?隐式的调用了valueof方法
总结:Integer类型的数据:[-128~127]之间的数,取自初始化数组比较地址相同,范围之外new类型,地址不同
?List接口
List接口继承了Collection接口,List接口元素重复且有序
List接口继承了Collection接口的所有抽象方法,还多了一些特有办法
add---添加元素
public static void main(String[] args) {
List<String> list=new ArrayList<>();
//ArrayList类实现了List接口,向上转型
list.add("hello");//在末尾添加元素
list.add(0,"world");//在某一下标处添加
System.out.println(list);
}
remove---删除元素
public static void main(String[] args) {
List<String> list=new ArrayList<>();
//ArrayList类实现了List接口,向上转型
list.add("hello");//在末尾添加元素
list.add(0,"world");//在某一下标处添加
list.add("fine");
System.out.println(list);
list.remove("hello");
list.remove(1);//移除某一个下标的元素
System.out.println(list);
}
get---得到某一个下标的元素
public static void main(String[] args) {
List<String> list = new ArrayList<>();
//ArrayList类实现了List接口,向上转型
list.add("hello");//在末尾添加元素
list.add(0, "world");//在某一下标处添加
list.add("fine");
System.out.println(list);
String str = list.get(1);//返回某一个下标的元素
System.out.println(str);
}
?indexOf()---返回元素第一次出现的下标
lastIndexOf()---元素最后一个出现的下标
System.out.println(list.indexOf("world"));
System.out.println(list.lastIndexOf("world"));;///返回最后一次出现的索引
sort(Comparator<? super E>?c)---排序 ?
class Person{
int age;
String name;
public Person(int age, String name) {
this.age = age;
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
class Agesort implements Comparator<Person>{
@Override
public int compare(Person o1, Person o2) {
return (o1).age-o2.age;
}
}
class NameSort implements Comparator<Person>{
@Override
public int compare(Person o1, Person o2) {
return o1.name.compareTo(o2.name);
}
}
public class Text {
public static void main(String[] args) {
List<Person> list = new ArrayList<>();
list.add(new Person(10, "张三"));
list.add(new Person(20, "李四"));
list.add(new Person(5, "王五"));
System.out.println(list);
list.sort(new Agesort());
System.out.println(list);
System.out.println("==============");
System.out.println(list);
list.sort(new NameSort());
System.out.println(list);
}
}
?subList()---返回区间内部的元素
public static void main(String[] args) {
List<String> list = new ArrayList<>();
//ArrayList类实现了List接口,向上转型
list.add("hello");//在末尾添加元素
list.add(0, "world");//在某一下标处添加
list.add("world");
System.out.println(list);
List list1=list.subList(0,2);//返回区间内的元素 左闭右开区间
System.out.println(list1);
list1.add("ok");
System.out.println(list);
}
?对于list1的更改会引起list的变化
?这个方法返回了一个SubList,这个类是ArrayList中的一个内部类。
调用这个类时,调用其构造方法,不是新建了一个类,而是引用了原来的类,只不过返回了其中的一部分而已
ArrayList集合
顺序表
构造方法
public static void main(String[] args) {
ArrayList<String> arrayList=new ArrayList<>();
//调用没有参数的构造方法
ArrayList<String> arrayList1=new ArrayList<>(20);
//数组的初始空间是20
ArrayList<String> arrayList2=new ArrayList<>(arrayList);
//顺序表先以arrayList填充
}
?add---增加元素
?调用没有参数的构造方法,底层数组为空,能放得下元素证明add方法肯定进行了扩容
public static void main(String[] args) {
ArrayList<String> arrayList=new ArrayList<>();
arrayList.add("hello");
System.out.println(arrayList);
}
?总结:当调用没有参数的构造方法时,数组为空,添加元素时,会修改默认大小为10,后正常进行1.5倍增容
remove---删除元素
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<>();
list.add(2);
list.add(8);
System.out.println(list);
list.remove(0);
System.out.println(list);
}
Collection集合的遍历
Iterator遍历集合
Iterator接口是Java集合框架的一部分,主要用于遍历元素,Iterator对象被称为迭代器
public static void main(String[] args) {
ArrayList<String> arrayList=new ArrayList<>();
arrayList.add("hello");
System.out.println(arrayList);
}
内部重写了toString方法?
public static void main(String[] args) {
ArrayList<String> arrayList=new ArrayList<>();
arrayList.add("hello");
arrayList.add(0,"world");
Iterator<String> stringIterator =arrayList.iterator();
while(stringIterator.hasNext()){
String s=stringIterator.next();
System.out.print(s+" ");
}
}
?迭代器的删除异常
public static void main(String[] args) {
ArrayList<String> arrayList=new ArrayList<>();
arrayList.add("hello");
arrayList.add(0,"world");
ListIterator<String> stringIterator = arrayList.listIterator();
while(stringIterator.hasNext()){
stringIterator.remove();
System.out.print(stringIterator.next()+" ");
}
}
?为了解决这一个问题:先迭代元素,后删除,避免对同一个迭代器remove多次而抛出异常
public static void main(String[] args) {
ArrayList<String> arrayList=new ArrayList<>();
arrayList.add("hello");
arrayList.add(0,"world");
Iterator<String> stringIterator = arrayList.iterator();
while(stringIterator.hasNext())
System.out.print(stringIterator.next()+" ");
System.out.println("\n+++++++++++++++++");
stringIterator = arrayList.iterator();
while(stringIterator.hasNext()) {
String s= stringIterator.next();
if(s.equals("world"))
stringIterator.remove();
}
stringIterator = arrayList.iterator();
while(stringIterator.hasNext())
System.out.print(stringIterator.next()+" ");
}
迭代器也有不同的实现类,每个实现类有特有的方法
listIterator:ListIterator在Iterator基础上提供了add、set、previous等对列表的操作。
public static void main(String[] args) {
ArrayList<String> arrayList=new ArrayList<>();
arrayList.add("hello");
arrayList.add(0,"world");
ListIterator<String> stringIterator = arrayList.listIterator();
while(stringIterator.hasNext())
System.out.print(stringIterator.next()+" ");
System.out.println("\n+++++++++++++++++");
stringIterator = arrayList.listIterator();
while(stringIterator.hasNext()) {
String s= stringIterator.next();
if(s.equals("world"))
stringIterator.add("hi");//listIterator的add方法
}
stringIterator = arrayList.listIterator();
while(stringIterator.hasNext())
System.out.print(stringIterator.next()+" ");
System.out.println(arrayList);
}
ArrayList集合的ConcurrentModificationException异常
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("hello");
arrayList.add(0, "world");
ListIterator<String> stringIterator = arrayList.listIterator();
while(stringIterator.hasNext()) {
String s= stringIterator.next();
if(s.equals("world"))
arrayList.add(s);//调用ArrayList集合的方法
}
}
?异常出现的原因
从异常信息可以发现,异常出现在ArrayList类中Itr类的checkForComodification()方法中
?发现了异常原因:代码的修改次数和期望修改次数不一样
调用了ArrayList的add方法,其内部实现了对modCount的改变
在ArrayList集合中,方法对代码进行修改时会存在modCount来记录修改次数,当修改次数和预计修改次数不一致时,就会抛出异常ConcurrentModificationException
单线程的解决方法---调用迭代器的方法
?发现迭代器中也有add等方法,但是其多了一条语句:expectedModCount = modCount;解决了异常
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("hello");
arrayList.add(0, "world");
ListIterator<String> stringIterator = arrayList.listIterator();
while(stringIterator.hasNext()) {
String s= stringIterator.next();
if(s.equals("world"))
stringIterator.add(s);
}
}
多线程的解决方法---使用CopyOnWriteArrayList
CopyOnWriteArrayList是线程安全的,适用于多线程
public static void main(String[] args) {
CopyOnWriteArrayList<Integer> list = new CopyOnWriteArrayList<>();
list.add(2);
Iterator<Integer> iterator = list.iterator();
while(iterator.hasNext()){
Integer integer = iterator.next();
if(integer==2)
list.remove(integer);
}
}
for-each遍历
public static void main(String[] args) {
ArrayList<String> arrayList=new ArrayList<>();
arrayList.add("hello");
arrayList.add(0,"world");
for (String s:arrayList
) {
System.out.println(s);
}
}
for循环遍历
public static void main(String[] args) {
ArrayList<String> arrayList=new ArrayList<>();
arrayList.add("hello");
arrayList.add(0,"world");
for (int i=0;i<arrayList.size();i++)
System.out.println(arrayList.get(i));
}
|