Java基础——集合

首先呢,给大家讲一下集合的由来:java的思想是面向对象思想,如果想统一的管理所有的对象,就涉及到用容器来储存对象,而对象数组是可以存储对象的,但是数组有一个缺点就是长度固定,为了突破这一限制 ,集合就应运而生了。

数组和集合的优缺点

长度:数组固定,集合可变;
内容:集合只能存储引用类型,数组可以存储基本类型和引用类型。

集合体系

单列集合顶层接口
Collection
	|-List有序(存入和取出顺序相同) 存入的元素可以重复 有索引 可以通过索引来操作元素
		|-ArrayList	数组结构
		|-LinkedList	链表结构
		|-Vector	数组结构
	|-Set 无序(存入和取出顺序不同) 存入的元素不可以重复
		|-HashSet	 哈希算法
		|-TreeSet	二叉树算法
双列集合
Map
	|-HashMap
	|-TreeMap
Collection

常用方法

boolean add(E e):向集合中添加元素e,添加成功返回true,添加失败返回false(List集合永远添加成功 Set集合就有可能添加失败因为Set集合会去掉重复元素)
boolean remove(Object o):删除集合中的元素o,删除成功则true,删除失败则false
void clear():清空集合里面的元素
boolean contains(Object o):集合是否包含元素o,如果包含返回true,如果不包含返回false
boolean isEmpty():判断集合是否为空
int size():集合的长度
集合的长度:c.size();
字符串长度:s.length();
数组的长度:arr.length;

代码演示:

public static void main(String[] args) {
    Collection c = new ArrayList();		//父类引用指向子类对象
    boolean b1 = c.add("abc");			//添加一个字符串
    boolean b2 = c.add(true);			//自动装箱new Boolean(true);
    boolean b3 = c.add(100);			//自动装箱new Integer(100);
    boolean b4 = c.add(new Student("张三",23));	//添加一个自定义对象	
    boolean b5 = c.add("abc");			//添加一个重复的字符串

    System.out.println(b1);		//true
    System.out.println(b2);		//true
    System.out.println(b3);		//true
    System.out.println(b4);		//true
    System.out.println(b5);		//true

    System.out.println(c);//[abc, true, 100, Student [name=张三, age=23], abc]  
    //ArrayList的父类重写了Object的toString()

    Collection c1 = new ArrayList();		//父类引用指向子类对象		
    c1.add("a");
    c1.add("b");
    c1.add("c");
    c1.add("d");

    c1.remove("b");					//删除指定元素
    System.out.println(c1);				//[a, c, d]

    System.out.println(c1.contains("b"));		//false  判断是否包含
    System.out.println(c1.contains("c"));		//true  判断是否包含

    System.out.println(c1.size()); 			//3  长度为3 

    System.out.println(c1.isEmpty());		//false  不为空

    c1.clear();					//清空集合										//清空集合
    System.out.println(c1);				//[]
}

Object[] toArray():集合转数组 (可以用来遍历)

代码演示:

public static void main(String[] args) {
    Collection c = new ArrayList();
    c.add(new Student("张三", 23));		//自动类型提升:Object obj = new Student("张三",23);
    c.add(new Student("李四", 24));
    c.add(new Student("王五", 25));
    c.add(new Student("赵六", 26));

    Object[] arr = c.toArray();		//将集合转换成数组
    for (int i = 0; i < arr.length; i++) {
        Student s = (Student)arr[i];	//向下转型
        System.out.println(s.getName() + "..." + s.getAge());
    }
}

不常用的带All的方法

boolean addAll(Collection c):添加 c里面的所有元素
boolean removeAll(Collection c):删除交集
boolean containsAll(Collection c):是否全部包含
boolean retainAll(Collection<?> c):取交集

迭代器 Iterator

迭代器的原理

Iterator是个接口,是通过集合里面的内部类实现的。迭代器是对集合进行遍历,而每一个集合内部的存储结构都是不同的,所以每一个集合存和取都是不一样,那么就需要在每一个类中定义hasNext()和next()方法。这样做是可以的,但是会让整个集合体系过于臃肿,迭代器是将这样的方法向上抽取出接口,然后在每个类的内部定义自己迭代方式,这样做的好处有二:第一、规定了整个集合体系的遍历方式都是hasNext()和next()方法;第二、代码有底层内部实现,使用者不用管怎么实现的,会用即可。

代码演示:

public static void main(String[] args) {
	Collection c = new ArrayList();
	c.add(new Student("张三", 23));		//Object obj = new Student("张三",23);
	c.add(new Student("李四", 24));
	c.add(new Student("王五", 25));
	c.add(new Student("赵六", 26));
		
	//获取迭代器
	Iterator it = c.iterator();
	while(it.hasNext()) {
        System.out.println(((Student)it.next()).getName()+"  "+
					((Student)it.next()).getAge());//如果这样写的话  打印结果为  zhangsan  14 并且报错java.util.NoSuchElementException 因为next()方法调用一次,指针就往后走一次
        
		Student s = (Student)it.next();	//所以一般while循环里面 就出现一次next(),如果想使用多次 请用一个变量接受next()方法的返回值 
		System.out.println(s.getName()+"  "+s.getAge());
	}
}
List接口

List的特有方法

void add(int index,E element);在指定的index位置插入element元素
E remove(int index);删除index位置上的元素
E get(int index);获取指定index位置上的元素。可以用来遍历List集合,而且这种遍历方式是List特有的遍历方式
E set(int index,E element);把集合中index位置上的元素用element元素替换

concurrentModificationException:并发修改异常

原因:在用迭代器遍历集合的时候,我们通过集合改变了元素,而迭代器是通过集合得到的,集合发生了改变,而迭代器还是通过原来的集合得到的,所以产生了并发修改异常。
解决:

  1. 通过迭代器遍历集合的时候,我们通过迭代器来改变集合元素,而这时候原来Iterator没有添加元素的方法,所以就用ListIterator,因为ListIterator里面有add方法
  2. 通过普通for循环来遍历集合的时候,用集合来改变元素

代码演示:

public static void main(String[] args) {
    List list = new ArrayList();
    list.add("a");				//Object obj = new String();
    list.add("b");
    list.add("world");
    list.add("c");
    list.add("d");
    list.add("e");

    //报并发修改异常原因:
    Iterator it = list.iterator();	//获取迭代器
    while(it.hasNext()) {			//判断集合中是否有元素
        String str = (String)it.next();	//向下转型
        if("world".equals(str)) {
            //遍历的同时在用集合调用add方法增加元素,并发修改ConcurrentModificationException
            list.add("javaee");	
        }
    }

    //解决方案一
    ListIterator lit = list.listIterator();//获取迭代器(List集合特有的)可以通过hasPrevious()和previous()来往前遍历
    while(lit.hasNext()) {
        String str = (String)lit.next();//向下转型
        if("world".equals(str)) {
            lit.add("javaee");	//遍历的同时用迭代器调用add方法添加元素就没问题
        }
    }

    //解决方案二
    for (int i = 0; i < list.size(); i++) {	//通过普通for循环来遍历集合的时候,用集合来改变元素
        String str = (String)list.get(i);
        if("world".equals(str)){
            list.add("javaee");
        }
    }

    System.out.println(list);
}
ArrayList

基本上都是从List实现的方法,因此没有特有的方法。
案例:ArrayList去除集合中字符串的重复值(字符串的内容相同)

public static void main(String[] args) {
	ArrayList list = new ArrayList();
	list.add("a");
	list.add("a");
	list.add("b");
	list.add("b");
	list.add("c");
	list.add("c");
	list.add("c");
	list.add("c");
		
	ArrayList newList = getSingle(list);
	System.out.println(newList);
}
/*
* 分析:
* 1,创建新集合
* 2,根据传入的集合(老集合)获取迭代器
* 3,遍历老集合
* 4,通过新集合判断是否包含老集合中的元素,如果包含就不添加,如果不包含就添加
*/
public static ArrayList getSingle(ArrayList list) {
    ArrayList newList = new ArrayList<>();		//1,创建新集合
    Iterator it = list.iterator();			//2,根据传入的集合(老集合)获取迭代器

    while(it.hasNext()) {				//3,遍历老集合
        Object obj = it.next();			//记录住每一个元素
        if(!newList.contains(obj)) {	//如果新集合中不包含老集合中的元素
            newList.add(obj);			//将该元素添加
        }
    }
    return newList;
}
LinkedList

public void addFirst(E e)将指定元素插入此列表的开头。
public void addLast(E e)将指定元素添加到此列表的结尾。
public E removeFirst()移除并返回此列表的第一个元素。
public E removeLast()移除并返回此列表的最后一个元素。
public E getFirst()返回此列表的第一个元素。
public E getLast()返回此列表的最后一个元素。

代码演示:

public static void main(String[] args) {
    LinkedList list = new LinkedList();
    list.addFirst("a");
    list.addFirst("b");
    list.addFirst("c");
    list.addFirst("d");
    list.addLast("e");
    System.out.println(list.getFirst());	//d
    System.out.println(list.getLast());	//e
    System.out.println(list.removeFirst());	//d
    System.out.println(list.removeLast());	//e
    System.out.println(list);		//[c, b, a]
}

栈和队列:
栈: 先进后出
队列: 先进先出

Vector

jdk1.0出现1.2并入到List体系,后来被ArrayList替代,所以了解即可。

附:
数组结构:查询快 增删慢
链表结构:查询慢 增删快

List的三个儿子的特点
ArrayList:查询快 增删慢 不安全 效率高
LinkedList:查询慢 增删快 不安全 效率高
Vector:查询快 增删慢 安全 效率低

好了集合部分就先说到这了,想了解更多学习知识,请关注微信公众号“阿Q说代码”,获取更多学习资料吧!你也可以后台留言说出你的疑惑,阿Q将会在后期的文章中为你解答。每天学习一点点,每天进步一点点。

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿Q说代码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值