集合框架——List集合
一.集合框架中特有的方法:迭代器(Iterator)
增强for循环 下标遍历
引发的面试问题:
Collection.remove 与 Iterator.remove 的区别:
1、在集合遍历的过程中,如果说调用collection.remove方法的时候,只会调用其中一部分的元素
2、Iterator.next()指的是指针下移
3、如果说在Iterator中遍历的时候,用collection去操作容器中的元素会报:当前改变异常(concurrentModifyExcepton)
package com.xfz.list;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/**
- 这个类是collection接口中特别方法
- Iterator迭代器
- 集合的remove方法与迭代器的remove方法有什么区别
- 1.在迭代器或者foreach循环删除的时候容易出现什么常见的问题 it.next():容器中的指针往下移(下一个)
- 2.在迭代器中执行collection.remove方法
- java.util.ConcurrentModificationException当前改变异常
- 本质来说:这是一个并发问题
- @author ld
*/
public class CollectionDemo {
public static void main(String[] args) {
Collection c=new ArrayList();
c.add(22);
c.add(23);
c.add(26);
c.add(28);
c.add(55);
//增强for循环
for (Object object : c) {
System.out.println(object);
}
// for (int i = 0; i < c.size(); i++) {
//
// }
//迭代器是集合所特有的遍历方式
// Iterator it=c.iterator();
// while(it.hasNext()) {
// System.out.println(it.next());
// int num=(int) it.next();
// if(num%2==0) {
//// System.out.println(it.next());
//// System.out.println(num);
// //区别:it.next():指针往下移(下一个)
// }
// }
Iterator it=c.iterator();
while(it.hasNext()) {
// System.out.println(it.next());
int num=(int) it.next();
if(num%2==0) {
// System.out.println(it.next());
// System.out.println(num);
// it.remove(); //运行结果为23、25
c.remove(num); //出现报错(当前改变异常)
}
}
System.out.println©;
}
}
二.List集合(常用在实现类的区别)
常用在实现类之间的区别
ArrayList 数组结构 查询修改快、增删慢 不同步 增长因子0.5
Vector 数组结构 查询修改快、增删慢 同步的 增长因子2
LinkedList 链式结构 增删快、查询修改慢
ArrayList
package com.xfz.list;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Vector;
/**
- list所特有的方法listIterator
- @author ld
*/
public class ListDemo {
public static void main(String[] args) {
List c=new ArrayList();
c.add(22);
c.add(23);
c.add(26);
c.add(28);
c.add(55);
// Iterator it=c.iterator();
// while(it.hasNext()) {
// System.out.println(it.next());
// }
ListIterator lt=c.listIterator();
// while(lt.hasNext()) {
// System.out.println(lt.next());
// } //注释掉这一段下一段运行会得不到数据
while(lt.hasPrevious()) {
//previous():取上一个元素
System.out.println(lt.previous());
}
}
}
ArrayList与vector的区别
package com.xfz.list;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Vector;
/**
- 面试题:
- ArrayList与array的区别
- 1.list的长度可变 数组长度固定
- 2.list可以存放各类元素对象,而数组一旦申明 只能存放对应的类型
- Arraylist如何进行性能调优?
- 为什么list集合底层是数据结构 但是数组长度优势是固定的 而list长度又可变呢?
- 论证增长因子
- @author ld
*/
public class ListDemo2 {
//ArrayList
public static void main(String[] args) {
ArrayList al=new ArrayList<>(50); //ArrayList增长因子是0.5
for (int i = 1; i < 80; i++) {
al.add(i);
System.out.print(i+",");
getLen(al);
}
}
public static void getLen(ArrayList al) {
try {
Field f=al.getClass().getDeclaredField(“elementData”);
f.setAccessible(true);
Object obj=f.get(al);
Object[] elementData=(Object[]) obj;
System.out.println(“当前al容器的底层数组长度”+elementData.length);
} catch (NoSuchFieldException | SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//Vector
// public static void main(String[] args) {
// Vector al=new Vector(50); //Vector增长因子是2
// for (int i = 1; i < 80; i++) {
// al.add(i);
// System.out.print(i+",");
// getLen(al);
// }
// }
// public static void getLen(Vector al) {
// try {
// Field f=al.getClass().getDeclaredField(“elementData”);
// f.setAccessible(true);
// Object obj=f.get(al);
// Object[] elementData=(Object[]) obj;
// System.out.println(“当前al容器的底层数组长度”+elementData.length);
// } catch (NoSuchFieldException | SecurityException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (IllegalArgumentException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (IllegalAccessException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//
// }
}
三.LinkedList
堆栈结构:特点:先进后出
队列结构:特点:先进先出
package com.xfz.list;
import java.util.Iterator;
import java.util.LinkedList;
/**
- 面试题:
- 通过linkedlist集合来自制作一个堆栈结构的容器
- 获取制作一个队列结构的容器
- 堆栈结构:特点:先进后出
- 队列结构:特点:先进先出
- @author ld
*/
public class LinkedListDemo {
public static void main(String[] args) {
DuiZhan dz= new DuiZhan();
//DuiLie dl=new DuiLie();
dz.push(“a”);
dz.push(“b”);
dz.push(“c”);
dz.push(“d”);
dz.push(“e”);
dz.bianli();
}
}
/***
- 堆栈结构的容器
- @author ld
/
class DuiZhan{
private LinkedList ll=new LinkedList<>();
/**
* 往堆栈的容器中添加元素
* @param obj
*/
public void push(Object obj) {
ll.addFirst(obj);
}
public Object pop() {
//拿出一个移除一个,不能用getfirst()因为一直得到的是第一个。并且不能边遍历边移除,会得不到所有元素
return ll.removeFirst();
}
public void bianli() {
Iterator it=ll.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
/***
- 队列结构的容器
- @author ld
/
class DuiLie{
private LinkedList ll=new LinkedList<>();
/**
* 往队列的容器中添加元素
* @param obj
*/
public void push(Object obj) {
ll.addLast(obj);
}
public Object pop() {
return ll.removeFirst();
}
public void bianli() {
Iterator it=ll.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
}
}
四.List去重复问题
结论:list中的contains方法,底层调用了对象的equals方法
package com.xfz.list;
import java.util.ArrayList;
/**
- 对ArrayList中的元素去重复
- 1.元素是字符串
- 2.元素是自定义
- 需求
- 判定两个人是同一个人的依据:名字和年龄相同
- 集合collection的contains方法在调用的时候底层调用容器元素对象的equals方法
- 之前元素对象时String
- 现在的元素对象是Object
- @author ld
*/
public class ArrayListDemo {
public static void main(String[] args) {
ArrayList al=new ArrayList<>();
//元素是字符串
// al.add(“zhangsan”);
// al.add(“lisi”);
// al.add(“wangwu”);
// al.add(“zhaoliu”);
// al.add(“zhangsan”);
//元素是自定义
al.add(new Person("zhangsan",30));
al.add(new Person("lisi",20));
al.add(new Person("wangwu",30));
al.add(new Person("zhaoliu",19));
al.add(new Person("zhangsan",30));
ArrayList newAl=repeat(al);
System.out.println(newAl.size());//运行结果为5
}
/**
* 思路:
* ArrayList al这个容器中是有重复元素的
* 1.建立一个新容器
* 2.将老的容器遍历取出其中的元素
* 3.如果说这个元素真的存在于新容器中,那么不再往新容器中加入。如果不存在就加入
* @param al
* @return
*/
public static ArrayList repeat(ArrayList al) {
ArrayList newAl=new ArrayList<>();
for (Object obj : al) {
if(!newAl.contains(obj)) {
newAl.add(obj);
}
}
return newAl;
}
}
class Person{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
}
@Override
public boolean equals(Object obj) {
Person p= (Person) obj;
//System.out.println(p.name+"---"+this.name);
return p.name.equals(this.name) && p.age==this.age;
}
}