JAVA学习日志9(List集合)

JAVA学习日志9

集合
数组是用来存放相同数据类型的一个容器,长度是固定的。固定的长度有扩展性差。而集合也可以用来存储数据且长度不固定。

  • 数组和集合
    1.相同点:都可以用来存储数据 都可以通过索引来获取数据
    2.不同点:数组长度不可变而集合长度是可变的 数组可以存基本数据类型也可以存引用数据类型,而集合只能存引用数据类型,当集合涉及到基本数据类型时使用其包装类
  • 集合的架构
    单列集合在这里插入图片描述
    双列集合
    在这里插入图片描述

Collection
Collection 是一个接口不能实例话,只能实例化其子类,如 Collection col = new ArrayList();

  • 一些方法

    boolean add(E e)向集合中添加(这里的E是范型)
    boolean contains(Object o)集合中是否包含指定元素
    boolean isEmpty()判断集合中是否有元素
    void clear()清空集合中所以的元素
    boolean remove(Object o)删除集合中指定的数据
    int size()获取集合的长度
    boolean addAll(Collection<? extends E> c)集合的合并,把被调用者的元素追加到调用者里
    boolean removeAll(Collection<?> c)把调用者和被调用者中重合的部分 从调用者中移除(被调用者的不会发生任何改变)
    boolean containsAll(Collection<?> c)判断被调用者的所有成员是否全部包含在调用者中
    boolean retainAll(Collection<?> c)真子集?

集合里的遍历方法(一)
把集合转换成数组来进行遍历,使用 Object[] toArray() 方法,遍历时使用数组的遍历方法

public static void main(String[] args) {
	Collection<MyClass> list = new ArrayList<MyClass>();
	list.add(new MyClass("No1","小明",19));
	list.add(new MyClass("No2","小红",19));
	//集合装换为数组
	Object[]line= list.toArray();
	//遍历输出
	for(int i=0;i<line.length;i++) {
		System.out.println(line[i].toString());
//		MyClass temp = (MyClass)line[i];
//		System.out.println(temp.getId()+" "+temp.getName()+" "+temp.getAge());
	}
}

toString 方法在MyClass里进行了重写,所以object类里直接使用了MyClass的toString方法,若使用MyClass的其他特有方法,需要向下转型。

集合里的遍历方法(二)
使用迭代器 iterator来进行遍历

  • 一些方法
    boolean hasNext()用于来判断是否有下一个元素 如果有返回 true 没有false
    E next()返回下一个元素
    void remove()删除迭代器中的元素,删除的是当前指向的那个元素
    Iterator iterator()把集合转换成迭代器,由集合调用
public static void main(String[] args) {
	Collection<MyClass> list = new ArrayList<MyClass>();
	list.add(new MyClass("No1","小明",19));
	list.add(new MyClass("No2","小红",19));
	//把集合转换为迭代器
	Iterator<MyClass> line = list.iterator();
	//遍历输出
	while(line.hasNext()) {
		System.out.println(line.next().toString());
	}
}

集合装换迭代器时,范型指明的了时MyClass类,所有ine.next()返回的也是MyClass类,故可以使用MyClass类里的一些特有方法

  • 迭代器注意点:
    1.迭代器需要先判断 hasNext() 然后再获取值
    2.如果迭代器没有给泛型 默认返回都是Object 需要进行强制类型转换
    3.next() 获取的是下一个元素 还会把指针往后进行移动

List接口
list是有序的,有索引的

  • 一些方法( 都是根据索引来进行操作)
    void add(int index,E element)根据索引来进行增加
    E set(int index, E element)进行索引来进行修改
    E remove(int index)根据索引来进行删除
    E get(int index)根据索引得到具体的对象

集合里的遍历方法三
使用list的方法遍历

public static void main(String[] args) {
	List<MyClass> list = new ArrayList<MyClass>();
	list.add(new MyClass("No1","小明",19));
	list.add(new MyClass("No2","小红",19));
	for(int i=0;i<list.size();i++) {
		System.out.println(list.get(i).toString());
	}
}

并发异常
用迭代器来进行遍历,使用集合来进行添加数据 会产生并发异常,如下面这样会产生ConcurrentModificationException

public static void main(String[] args) {
	ArrayList<MyClass> list = new ArrayList<MyClass>();
	list.add(new MyClass("No1","小明",19));
	list.add(new MyClass("No2","小红",19));
	//把集合转换为迭代器
	Iterator<MyClass> line = list.iterator();
	while(line.hasNext()) {
		System.out.println(line.next().toString());
		//使用集合添加元素
		list.add(new MyClass("No3","小黑",19));
	}
}
  • 解决办法
    1.使用迭代器来进行添加 使用迭代器来进行遍历
    2.使用集合来进行遍历 使用集合来进行添加

  • 使用迭代器来进行添加 使用迭代器来进行遍历
    迭代器Iterator没有添加的元素的方法,所以需要使用到它的子类ListIterator,ListItreator不仅继承了Iterator的方法还有add()先当前指向的位置的下一位插入元素previous()获取前一个元素hasPrevious()判断是否有前一个元素

public static void main(String[] args) {
	ArrayList<MyClass> list = new ArrayList<MyClass>();
	list.add(new MyClass("No1","小明",19));
	list.add(new MyClass("No2","小红",19));
	//把集合转换为迭代器
	ListIterator<MyClass> line = list.listIterator();
	while(line.hasNext()) {
		System.out.println(line.next().toString());
		//使用迭代器添加元素
		line.add(new MyClass("No3","小黑",19));
	}
}

添加完新元素后需要再次遍历集合才可以访问到新元素

ArrayList和LinkedList
ArrayList和LinkedList区别实际就是一维数组和链表的区别

  • ArrayList没有自己独有的方法,其方法都是继承于list
  • LinkedList 常用的方法:
    public void addFirst(E e)将指定元素插入此列表的开头
    public void addLast(E e)将指定元素添加到此列表的结尾
    public E removeFirst()移除并返回此列表的第一个元素
    public E removeLast()移除并返回此列表的最后一个元素
    public E getFirst()返回此列表的第一个元素
    public E getLast()返回此列表的最后一个元素

泛型
使用场景:当使用集合不确定其数据类型的时候,我就可以使用泛型 泛型可以理解为是一个变量 这个变量主要是用于来接收数据类型

  • 泛型的好处:
    1.提高代码的安全性 把运行错误的提前到编译出错
    2.不需要进行反复强制类型转换

  • 定义泛型使用一些字母 一般是大写 E T W K V

  • 定义一个泛型类
    访问修饰符 class 类名<泛型T,泛型W>{}

  • 方法定义泛型
    语法: 访问修饰 <泛型> 返回值类型 方法的名称(参数){}
    注意点: 普通方法可以使用类的泛型,静态方法不能使用类的泛型 因为类的泛型在实例化的时候确定的

  • 泛型定义接口
    语法:interface 接口名<泛型T,泛型W>{}
    实现类 :

    1. 直接覆盖其泛型(也就是在实现类确定具体的泛型 )
    2. 实现类继续使用接口定义的泛型
  • 范型的通配符

    1. ? 用于表示任意的类型 一般是用于方法传递参数的时候使用
    public void show(List<?> list) {
      	
    }
    
    1. <? extends E> 泛型只能是 E 泛型本身 或者是其子类
    2. <? super E> 泛型只能是 E 泛型本身 或者是其父类
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值