重点
1.List集合特有的功能
void add(int index,E element) 在指定位置添加元素
E remove(int index) 删除指定位置的元素
E get(int index) 获取指定位置元素
E set(int index,E element) 修改指定位置的元素
public static void main(String[] args) {
// TODO Auto-generated method stub
//List集合的特有功能概述和测试
/* void add(int index,E element)
E remove(int index)
E get(int index)
E set(int index,E element)*/
//Collection col1 = new ArrayList();
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);
}
2.List集合的遍历
掌握size和get方法的应用
List list = new ArrayList();
list.add(new Student(“aa”,23));
list.add(new Student(“ab”,23));
list.add(new Student(“ac”,23));
for(int i=0;i<list.size();i++){
Object obj = list.get(i);
sysout(obj);
}
- 集合的遍历方式
- 1.把集合转成数组
- 2.使用集合中的迭代器
- 3.通过List的size()和get()方法结合来遍历List集合
public class Demo01 {
public static void main(String[] args) {
//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));
//遍历
/* list.get(0);
list.get(1);
list.get(2);*/
for(int i=0;i<list.size();i++){
Object obj = list.get(i);
System.out.println(obj);
}
}
}
3.并发修改异常
》如果对一个集合要一边遍历,一边添加元素,使用ListIterator这个类来实现
》ListIterator提供一个add方法来添加元素,
》ListIterator与Iterator这两个接口的关系继承
/**
* 掌握一个异常
* 1.ConcurrentModificationException:并发修改异常
* 2.默认情况下,不能一边遍历元素,一边添加元素
* 3.如果真想一边遍历元素,一边添加元素,建议使用另外一个类型的迭代器ListIterator
*
*/
public class Demo01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//并发修改异常产生的原因及解决方案
//需求:有一个集合,判断里面有没有"word"这个元素,如果有,就添加一个"javaee"元素
test2();
}
public static void test2() {
//Collection col1 = new ArrayList();
//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() {
//Collection col1 = new ArrayList();
//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");
}
}
}
}
4.ListIterator的其它方法
hasPrevious方法 : 判断是否有上一个元素
previous方法: 获取上一个元素
ListIterator iterator = list.listIterator();
while(iterator.hasNext()){
Object obj = iterator.next();
System.out.println(obj);
}
System.out.println("=========");
while(iterator.hasPrevious()){//判断是否有上一个元素
//取出上一个元素
Object obj = iterator.previous();
System.out.println(obj);
}
5.Vector
Vector实现List接口,方法基本上都添加了同步的声明,所以它是线程安全,性能差
Vector在开发中用的比较少
public class Demo01 {
public static void main(String[] args) {
/* 1.Vector介绍
* Vector在JDK1.0 版本就有了,从 Java 2 平台 v1.2 开始,
此类改进为可以实现 List 接口,
使它成为 Java Collections Framework 的成员,Vector 是同步的。
2.方法
public void addElement(E obj) 添加元素
public E elementAt(int index) 获取元素
public Enumeration elements() 遍历元素
3.Vector开发中相对来说用的少
原因:加锁,性能低,所以用的少
*/
//创建一个集合对象
Vector vector = new Vector();
//添加元素
/**
* synchronized:同步,加锁,线程安全
*/
vector.addElement("瑜伽");
vector.addElement("搏击");
vector.addElement("篮球");
//取元素
System.out.println(vector.elementAt(2));
//遍历Vector集合
//注意:取名时不要用enum,因为enum是一个关键字
//Enumeration:枚举
Enumeration enumeration =vector.elements();
while(enumeration.hasMoreElements()){
Object obj = enumeration.nextElement();
System.out.println(obj);
}
/*Vector v1 = new Vector();
//v1.add(e)
ArrayList list = new ArrayList();
list.add(e)*/
}
}
6.数据结构-数组和链表
数组:查找和修改快,增加删除慢
链表:查找和修改慢,增加删除快
7.LinkedList的使用
addFirst(E e) 把元素添加到第一个位置
addLast(E e) 把元素添加到最后的位置
getFirst() 获取第一个元素
getLast() 获取第二个元素
removeFirst() 删除第一个元素
public E removeLast() 移除第一个元素
public static void main(String[] args) {
// TODO Auto-generated method stub
//LinkedList的使用
/*方法
public void addFirst(E e)及addLast(E e)
public E removeFirst()及public E removeLast()
public E getFirst()及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());
}
8.栈和队列
栈:先进后出
队列:先进先出
9.用LinkedList模型栈数据结构
public class Demo01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//用LinkedList模拟栈数据结构
/**
* 分析:
* 1.栈(Stack)的特点:先进后出
* 2.栈的功能:进栈、出栈两个操作
*
* 写代码:栈(用一个类来表示)
* 类提供两个方法
* */
//创建一个栈对象
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);
}
}
class Stack{
//创建一个集合
LinkedList list = new LinkedList();
//进栈
public void in(Object obj){
//把元素添加集合
list.addFirst(obj);//集合前面的是栈顶,后面是栈底
//list.addLast(obj);
}
//出栈
public Object out(){
return list.removeFirst();
}
}
10.用LinkedList的pop和push方法
/**
* 掌握:
* LinkedList的pop和push方法
* --push:进栈
* --pop出栈
*
* 注意点:
* --出栈时,会把出栈的元素返回给你,也就是说pop方法有返回值
* --出栈时,如果栈里面没有元素了,调用出栈的方法会报错NoSuchElementException(没有这个元素异常)
*
*/
public class Demo01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//LinkedList其实已经提供了栈的功能
//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);
}
}
11.泛型集合
泛型:
- 1.泛型的作用:把类型明确的工作推前到创建对象或者调用方法的时候。
- 2.泛型是一种参数化类型,把类型当作参数一样传递来明确集合的元素类型
泛型好处
- 1.提高安全性(将运行期的错误转换到编译期)
- 2.省去强转的麻烦
/***
* 1.如果集合添加基本数据类型,内部会提升为包装类型
* int -> Integer
* double -> Double
*
* 2.List list = new ArrayList(); 这样声明一个集合对象,默认是可以添加任何类型的元素
*
* 3.如果在声明集合时,不添加泛型,就会有安全隐患(类型转换异常)
*
* 4.声明一个泛型集合:List<String> list = new ArrayList<String>();
* 代表list只能存字符串元素
*
*/
public class Demo01 {
public static void main(String[] args) {
//集合泛型:
/**
* 泛型:
* 1.泛型的作用:把类型明确的工作推前到创建对象或者调用方法的时候。
* 2.泛型是一种参数化类型,把类型当作参数一样传递来明确集合的元素类型
*
* 泛型好处
* 1.提高安全性(将运行期的错误转换到编译期)
* 2.省去强转的麻烦
*/
//声明一个泛型集合
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);
}
}
public static void test1() {
List list = new ArrayList();
//添加不同类型的元素到集合
list.add("Gosling");//->String
list.add(new Student("tony",23));//->Student
//list.add(12);//->Integer类型
//打印
System.out.println(list);
//遍历
for(int i=0;i<list.size();i++){
//取元素
Object obj = list.get(i);
//把Object转成String
String str = (String) obj;
System.out.println(obj.getClass());
}
}
}
练习题
1.去除ArrayList中重复元素
案例1:去除ArrayList中重复字符串元素方式
/**
* List:有序集合,有索引,存与取的顺序一样,可以重复
* 掌握:
* 掌握contains方法的灵活应用
*/
public class Demo01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//案例:去除ArrayList中重复字符串元素方式
//思路:创建新集合
//ArrayList list = new 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);
}
}
案例2:去除ArrayList中重复自定义对象元素
/**
* 掌握集合的contains方法的本质
* 1.如果是判断字符串在集合中是否存在,比较的字符串内容
* 2.如果是判断自定义对象在集合中是否存在,比较的对象的地址
* 3.调用contains方法,内部会调用对象equals方法
*
*
*/
public class Demo01 {
public static void main(String[] args) {
// TODO Auto-generated method stub
//案例:去除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);
}
}
面试题
1.List的面试题
一、Vector和ArrayList的区别
Vector是线程安全的,效率低
ArrayList是线程不安全的,效率高
共同点:都是数组实现的
二、ArrayList和LinkedList的区别
ArrayList底层是数组实现,查询和修改快
LinkedList底层是链表结构实现,增和删比较快,查询和修改比较慢
共同点:都是线程不安全的
三、List有三个子类,我们到底使用谁呢?
查询多用ArrayList
增删多用LinkedList
如果都多ArrayList
总结
通过今天的学习,掌握了List集合的三种遍历方式,分别有转成数组(toArray())、迭代器、size()和get()结合使用。其中迭代器里需要注意的是:如果对一个集合要一边遍历,一边添加元素,则用ListIterator这个,ListIterator提供一个add方法来添加元素,就不会报错。了解到List的三个实现类ArrayList、LinkedList、Vector的各自方法的使用以及特点。前两个是线程不安全的,效率高,后者是线程安全的,效率低,Vector是数组实现的。另外对泛型有了进一步的理解,使用泛型,提高了安全性(将运行期的错误转换到编译期) ,省去强转的麻烦。坚持敲代码,勤劳的码农!