List的三个子类的特点
ArrayList
底层数据结构是
数组
,查询快
,增删慢
线程不安全,效率高Vector
底层数据结构是
数组
,查询快
,增删慢
线程安全
,效率低
Vector相对ArrayList查询慢(线程安全的)
Vector相对LinkedList增删慢(数组结构)LinkedList
底层数据结构是
链表
,查询慢
,增删快
线程不安全
,效率高
List集合的特有功能概述
void add(int index,E element) 指定的位置插入元素
E remove(int index) 删除指定索引的元素
E get(int index) 获取指定索引的元素
E set(int index,E element) 替换指定索引的元素
List list = new ArrayList();
list.add("Java");
list.add("PHP");
list.add("Go");
list.add("H5");
System.out.println("list:" + list);
//指定的位置插入元素
list.add(3, "Python");
System.out.println("list:" + list);
//删除指定索引的元素
//list.remove("Java");
list.remove(1);
System.out.println("list:" + list);
//获取指定索引的元素
System.out.println(list.get(1));
//替换指定索引的元素
list.set(1, "C++");
System.out.println("list:" + list);
- 集合的遍历方式
把集合转成数组
使用集合中的迭代器
通过List的size()和get()方法结合来遍历List集合
//List集合存储学生对象并遍历
//通过List的size()和get()方法结合来遍历List集合
List list = new ArrayList();
list.add(new Student("apple", 12));
list.add(new Student("banana", 22));
list.add(new Student("orange", 32));
//遍历
for(int i=0;i<list.size();i++){
Object obj = list.get(i);
System.out.println(obj);
}
- 掌握一个异常
ConcurrentModificationException:并发修改异常
默认情况下,不能一边遍历元素,一边添加元素
如果真想一边遍历元素,一边添加元素,建议使用另外一个类型的迭代器ListIterator
public static void main(String[] args) {
// TODO Auto-generated method stub
//并发修改异常产生的原因及解决方案
//需求:有一个集合,判断里面有没有"word"这个元素,如果有,就添加一个"javaee"元素
test2();
}
public static void test2() {
//1.创建一个集合对象
List list = new ArrayList();//这中声明集合对象的方式比较常用
//2.添加元素
list.add("Hello");
list.add("word");
list.add("weclome");
System.out.println("list:" + list);
//3.遍历元素
//ListIterator -> Iterator
ListIterator li = list.listIterator();
while(li.hasNext()){
//4.取元素
Object obj = li.next();
String str = (String) obj;
//5.添加元素
if(str.equals("word")){
li.add("javaee");//通过迭代器添加元素
//list.add("javaee");//不用这个集合对象来添加元素
}
}
System.out.println("list:" + list);
}
public static void test1() {
//1.创建一个集合对象
List list = new ArrayList();//这中声明集合对象的方式比较常用
//2.添加元素
list.add("Hello");
list.add("word");
list.add("weclome");
System.out.println("list:" + list);
//3.遍历元素
Iterator iterator = list.iterator();
while(iterator.hasNext()){
//4.取元素
Object obj = iterator.next();
String str = (String)obj;//强制类型转换
//5.添加元素
if(str.equals("word")){
list.add("javaee");
}
}
}
- contains方法
有序集合,有索引,存与取的顺序一样,可以重复
public static void main(String[] args) {
//去除ArrayList中重复字符串元素方式
//创建新集合
List list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
list.add("a");
System.out.println("list:" + list);
//1.创建新集合
List newList = new ArrayList();
//2.创建list集合
for(int i=0;i<list.size();i++){
//3.取元素
Object obj = list.get(i);
System.out.println(obj.getClass());
//String str = (String) obj;
if(!newList.contains(obj)){//代表元素在新的集合中不存在
newList.add(obj);
}
}
//3.打印新集合:
System.out.println("newList:" + newList);
}
contains方法的本质
如果是判断字符串在集合中是否存在,比较的字符串内容
如果是判断自定义对象在集合中是否存在,比较的对象的地址
调用contains方法,内部会调用对象equals方法
public static void main(String[] args) {
//去除ArrayList中重复自定义对象元素
//创建新集合,重写对象的equals方法
//1.创建一个list集合
List list = new ArrayList();
//2.添加学生
list.add(new Student("刘备", 40));
list.add(new Student("关公", 42));
list.add(new Student("张飞", 39));
list.add(new Student("刘备", 40));
//3.打印学生
System.out.println("list:" + list);
//4.创建新的集合
List newList = new ArrayList();
//5.遍历学生
for(int i=0;i<list.size();i++){
//6.取出学生
Object obj = list.get(i);
System.out.println(obj.getClass());
//7.强转成学生类型
Student stu = (Student) obj;
//8.判断学生在新集合中是否存在
if(!newList.contains(stu)){
newList.add(stu);
}
}
System.out.println("newList:" + newList);
}
# Student类添加
@Override
public boolean equals(Object obj) {
//重写比较规则
Student other = (Student) obj;
return this.name.equals(other.name) && this.age == other.age;
}
LinkedList的使用
public void addFirst(E e)
public void addLast(E e)
public E removeFirst()
public E removeLast()
public E getFirst()
public E getLast()
public E get(int index)
//1.创建对象
LinkedList list = new LinkedList();
//2.把元素放在第1个位置
list.addFirst("a");
list.addFirst("b");
list.addFirst("c");
list.addFirst("d");
//3.把元素放在最后的位置
list.addLast("e");
list.addLast("f");
System.out.println("list:" + list);
//4.删除第一个元素
list.removeFirst();
list.removeFirst();
//5.删除最后一个元素
list.removeLast();
list.removeLast();
System.out.println("list:" + list);
//6.获取第一个元素
System.out.println(list.getFirst());
//7.获取最后一个元素
System.out.println(list.getLast());
- 用LinkedList模拟栈数据结构
栈(Stack)的特点:先进后出
栈的功能:进栈、出栈两个操作
class Stack{
//创建一个集合
LinkedList list = new LinkedList();
//进栈
public void in(Object obj){
//把元素添加集合
list.addFirst(obj);//集合前面的是栈顶,后面是栈底
//list.addLast(obj);
}
//出栈
public Object out(){
return list.removeFirst();
}
}
//创建一个栈对象
Stack stack = new Stack();
//进栈
stack.in("a");
stack.in("b");
stack.in("c");
stack.in("d");
//打印栈的数据
System.out.println("stack:" + stack.list);
//出栈
Object obj = stack.out();
System.out.println("出栈的元素是:" + obj);
System.out.println("stack:" + stack.list);
obj = stack.out();
System.out.println("出栈的元素是:" + obj);
System.out.println("stack:" + stack.list);
- LinkedList的pop和push方法
push:进栈
pop:出栈
出栈时,会把出栈的元素返回给你,也就是说pop方法有返回值
出栈时,如果栈里面没有元素了,调用出栈的方法会报错NoSuchElementException(没有这个元素异常)
//1.创建栈对象
LinkedList stack = new LinkedList();
//2.进栈
stack.push("a");
stack.push("b");
stack.push("c");
stack.push("d");
System.out.println("栈:" + stack);
stack.pop();
stack.pop();
stack.pop();
stack.pop();
stack.pop();
//3.出栈
Object obj = stack.pop();
System.out.println("出栈元素:" + obj);
System.out.println("栈:" + stack);
obj = stack.pop();
System.out.println("出栈元素:" + obj);
System.out.println("栈:" + stack);
- 集合泛型
泛型的作用:把类型明确的工作推前到创建对象或者调用方法的时候
泛型是一种参数化类型,把类型当作参数一样传递来明确集合的元素类型
提高安全性(将运行期的错误转换到编译期)
省去强转的麻烦
如果在声明集合时,不添加泛型,就会有安全隐患(类型转换异常)
//声明一个泛型集合
List<String> list = new ArrayList<String>();
list.add("Gosling");
list.add("David");
list.add("amy");
//list.add(12); 不能添加int
//list.add(new Student("we",23));//不能添加Student
//遍历
for(int i=0; i <list.size();i++){
String str = list.get(i);
System.out.println(str);
}
- 使用泛型ArrayList存储学生对象并遍历
//1.声明集合添加学生对象
List<Student> list = new ArrayList<Student>();
list.add(new Student("刘", 23));
list.add(new Student("李", 22));
list.add(new Student("贾", 21));
//2.遍历
Iterator<Student> iterator = list.iterator();
while(iterator.hasNext()){
Student stu = iterator.next();
System.out.println(stu);
}
- 声明一个泛型类和方法
class Tool<T>{
private T o;
public T getO() {
return o;
}
public void setO(T o) {
this.o = o;
}
//2.声明 泛型方法
/**
* 这个方法没有返回值,参数是泛型
*/
public void print(T t){
System.out.println(t);
}
//3.声明 泛型方法
/**
* 这个方法有返回值,无参数
*/
public T get(int index){
return null;
}
}
- 泛型接口
/**
* 数据访问层的接口
* 1.接口一般都定义方法
*
*/
interface DaoInterface<T>{
public List<T> findList();//查找表的所有信息
public T findByName(String name);//根据名字查询信息
public void update(T t);//修改信息
}
//泛型接口的实现类
class StudentDao implements DaoInterface<Student>{
@Override
public List<Student> findList() {
List<Student> list = new ArrayList<Student>();
list.add(new Student("小王", 18));
list.add(new Student("小李", 28));
return list;
}
@Override
public Student findByName(String name) {
// TODO Auto-generated method stub
return null;
}
@Override
public void update(Student t) {
// TODO Auto-generated method stub
}
}
class EmployeeDao implements DaoInterface<Employee>{
@Override
public List<Employee> findList() {
List<Employee> list = new ArrayList<Employee>();
list.add(new Employee("小郭", 38));
list.add(new Employee("小红", 28));
return list;
}
@Override
public Employee findByName(String name) {
// TODO Auto-generated method stub
return null;
}
@Override
public void update(Employee t) {
// TODO Auto-generated method stub
}
}
public static void main(String[] args) {
//创建泛型集合
List<String> list = new ArrayList<String>();
//泛型接口
/*
泛型接口概述
把泛型定义在接口
定义格式
public interface 接口名<泛型类型>
*/
//使用Dao
DaoInterface<Student> stuDao = new StudentDao();
System.out.println("stuList:" + stuDao.findList());
DaoInterface<Employee> empDao = new EmployeeDao();
System.out.println("empList:" + empDao.findList());
}
- 集合嵌套之List嵌套List
一个班的n学生是一个集合
一个学校n班也是一个集合
如何将这些数据用一个集合来表示
学校里有n个班,每个班有n个学生
//1、用集合来表示两个班级
List<Student> java1 = new ArrayList<Student>();
java1.add(new Student("小刘", 18));
java1.add(new Student("小张", 18));
java1.add(new Student("小关", 18));
List<Student> java2 = new ArrayList<Student>();
java2.add(new Student("李某某", 18));
java2.add(new Student("黄某某", 18));
java2.add(new Student("李某某", 18));
//2.用集合来表示学校school
List<List<Student>> school = new ArrayList<List<Student>>();
school.add(java1);
school.add(java2);
//3.遍历
//3.1遍历班级
for(List<Student> stus : school){
System.out.println("班级...");
//3.2 遍历学生
for(Student stu : stus){
System.out.println(stu);
}
}
List面试题
Vector和ArrayList的区别
1、Vector是线程安全的,效率低
2、ArrayList是线程不安全的,效率高
3、共同点:都是数组实现的ArrayList和LinkedList的区别
1、ArrayList底层是数组实现,查询和修改快
2、LinkedList底层是链表结构实现,增和删比较快,查询和修改比较慢
3、共同点:都是线程不安全的List有三个子类,我们到底使用谁呢?
1、查询多用ArrayList
2、增删多用LinkedList
3、如果都多用ArrayList