集合框架之list

一、了解什么是集合框架(Collection)

集合框架的由来:数据多了用对象进行存储,对象多了用集合来进行存储,而存储数据的方式(数据结构)各有不同,所以存储的容器也就有多种,从而形成了集合框架这一体系。
在集合框架中提供了一个内部类专门操作集合中的元素,这个内部类就是迭代器。

作用:

集合可以:

1、在类的内部,对数据进行组织;

2、简单而快速的搜索大数量的条目;

3、有的集合接口,提供了一系列排列有序的元素,并且可以在序列中间快速的插入或者删除元素;

4、有的集合接口,提供了映射关系,可以通过关键字(key)快速的查找到对应的唯一对象,而这个关键字可以是任意类型。

与数组的对比:

1、数组的长度固定,集合长度可变;

2、数组只能通过下标访问元素,下标类型只能是数字型,而有的集合可以通过任意类型查找所映射的具体对象。

整个集合框架大体上可以分为三种:
线性集合类型(List 接口:ArrayList、LinkedList…) 、
集合类型(Set 接口:HashSet、TreeSet…)、
映射类型(Map 接口:HashMap、TreeMap…)。
注意:Conllection接口不是Map集合的父接口!

Collection集合框架的顶级接口UML视图:
在这里插入图片描述

二、Collection之List接口

我们可以看到这类(List)容器是有下标的,可以按照下标去取、删除等等方式操作容器里的元素。
list的特点:有序、对象可以重复。
list有三种遍历方式:
①迭代器Iterator

List l=new ArrayList<>();
	l.add(1);
	l.add(2);
	l.add(3);
	l.add(4);
	l.add(5);
	
	Iterator it = l.iterator();
	while(it.hasNext()) {
	System.out.println(it.next());
	}

②foreach循环

List l=new ArrayList<>();
	l.add(1);
	l.add(2);
	l.add(3);
	l.add(4);
	l.add(5);
	
//	Iterator it = l.iterator();
//	while(it.hasNext()) {
//	System.out.println(it.next());
//	}
	
	for (Object obj : l) {
		System.out.println(obj);
	}

③通过下标循环遍历

List l=new ArrayList<>();
	l.add(1);
	l.add(2);
	l.add(3);
	l.add(4);
	l.add(5);
	
//	Iterator it = l.iterator();
//	while(it.hasNext()) {
//	System.out.println(it.next());
//	}
	
//	for (Object obj : l) {
//		System.out.println(obj);
//	}
	
	for (int i = 0; i < l.size(); i++) {
		System.out.println(l.get(i));
	}

1、list集合相对于collection集合所特有的方法:
凡是可以操作角标的方法都是该体系所特有的方法。
例如:

 增
 Add(index,element)
 Add(index,Collection)
  删
 Remove(index)
 
  改
  Set(index,element)
 
  查
 Get(index)
 subList(from,to)
 listIterator()
 index(element)

2、Iterator与ListIterator的区别:
list集合所特有的迭代器,ListIterator是Iterator的子接口
在迭代时,不可以通过集合对象的方法操作集合中的元素;
因为会发生并发修改异常(ConcurrentModificationException);
所以,在迭代时,只能通过迭代器来操作元素,课时Iterator的方法是有限的,Iterator只提供了判断、取出、删除的操作;
如果想要有其他的操作,如添加、修改等,就需要使用其子接口ListIterator,该接口只能list集合的listIterator方法来获取

  • listiteration还能倒着取值:
List l=new ArrayList<>();
	l.add(1);
	l.add(2);
	l.add(3);
	l.add(4);
	l.add(5);
	ListIterator it = l.listIterator();
	while(it.hasNext()) {//正常的list迭代器 从上往下取
		System.out.println(it.next());
	}
	while(it.hasPrevious()) {//倒着取的list迭代器  注:必须先运行正常的迭代器才能取
		//因为,一开始迭代器在最上面 运行完正常的迭代器后 到达了最下面才能从下面往上取
		//如果直接倒着取的话 会取不到值 
		System.out.println(it.previous());
	}

3、集合的remove方法与迭代器的remove方法有什么区别?
①在迭代器或者foreach循环删除的时候容易出现什么常见的问题 :
②在迭代器中执行collection.remove方法

Collection c=new ArrayList<>();
		c.add(1);
		c.add(2);
		c.add(3);
		c.add(4);
		c.add(5);
		//在迭代器或者foreach循环删除容易出现的问题
		Iterator it = c.iterator();
		while(it.hasNext()) {
			int num=(int)it.next();
			if(num % 2 == 0) {//当num 取模2==0时 num是偶数 
				System.out.println(it.next());//这里打印的是num的下一个数
				c.remove(num); 
				//当在这里进行删除时,会导致java.util.ConcurrentModificationException错误
				//多方对同一个元素进行操作 导致并发问题
			}
		}
		System.out.println(c);
		//		for (Object obj : c) {
//			int num = (int) obj;
//			if(num % 2 == 0) {
//				System.out.println(obj);//这里打印的是满足条件的obj
//				c.remove(obj);//当在这里进行删除时,会导致java.util.ConcurrentModificationException错误
//			//多方对同一个元素进行操作 导致并发问题
//				
//			}
//		}

List的三个子类的特点:

①Arraylist:

数组结构 增删慢,查询快 有连续下标 线程不同步 增长因子为1.5 10

② Vector:

数组结构 增删改查都慢 有连续下标 线程同步 增长因子2 10
Vector相对ArrayList查询慢(线程安全的)
Vector相对LinkedList增删慢(数组结构)

③Linkedlist:

链表结构 增删快,查询慢 没有连续下标

ArrayList 如何进行性能调优?

public class listdome2 {
 public static void main(String[] args) {
	ArrayList al = new ArrayList<>(80);
	for (int i = 0; i < 79; i++) {
		al.add(i);
		System.out.println(i+"---");
		getLength(al);//从这里我们可以得到arraylist底层数组的长度为多少 增长又为多少 
		
	}
	//如果我们需要对arraylist进行性能调优的话,直接对底层数组的初始长度进行扩大 new ArrayList<>(80);
 }
 
 public static void getLength(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 (Exception e) {
		e.printStackTrace();
		// TODO: handle exception
	}
 }
}

- 使用LinkedList完成堆栈和队列

示意图:
在这里插入图片描述

  • 堆栈结构(先进后出):
public class Linkedlistdemo {
public static void main(String[] args) {
	Duizhan dz = new Duizhan();//堆栈

	dz.push(1);
	dz.push(2);
	dz.push(3);
	dz.push(4);
	dz.push(5);
	
	dz.bianli();
	System.out.println("取前------取后");
	dz.pop(); 
	dz.bianli();
}
}
/**
 * 堆栈结构的容器  特点 先进后出   最先进去的最后出来 
 */
class Duizhan{
	private LinkedList ll = new LinkedList<>();
	/**
	 * 往堆栈结构里添加元素,每次放进去都是第一个
	 */
	public void push(Object obj) {
		ll.addFirst(obj);
	}
	/**
	 * 取的同时删除堆栈里的数据  每次取都是取第一个 就形成了先进后出
	 */
	public Object pop() {
		return ll.removeFirst();
	}
	/**
	 * 遍历
	 */
	public void bianli() {
		Iterator it = ll.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
	}
}



结果:
在这里插入图片描述

  • 队列(先进先出):
public class Linkedlistdemo {
public static void main(String[] args) {

	Duilie dz = new Duilie();//队列
	dz.push(1);
	dz.push(2);
	dz.push(3);
	dz.push(4);
	dz.push(5);
	
	dz.bianli();
	System.out.println("取前------取后");
	dz.pop(); 
	dz.bianli();
}
}
/**
 * 队列结构 特点:先进先出 先进去的先出来
 */
class Duilie{
	private LinkedList ll = new LinkedList<>();
	/**
	 * 往队列结构里添加元素,每次放进去都是第一个
	 */
	public void push(Object obj) {
		ll.addFirst(obj);
	}
	/**
	 * 取的同时删除队列里的数据  每次取都是取最后一个 就形成了先进先出
	 */
	public Object pop() {
		return ll.removeLast();
	}
	/**
	 * 遍历
	 */
	public void bianli() {
		Iterator it = ll.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
	}
}

结果:
在这里插入图片描述

集合框架ArrayList中的重复元素去重及其底层原理:

①字符串去重:

public class ArrayListdemo3 {
public static void main(String[] args) {
	ArrayList al = new ArrayList<>();
	al.add("q");
	al.add("w");
	al.add("e");
	al.add("r");
	al.add("t");
	al.add("t");
	
   ArrayList newal=al;//建立新的容器容纳
	System.out.println("去重前容器大小:"+newal.size());
	newal=repeat(al);
	System.out.println("去重后容器大小:"+newal.size());
	
}
/**
 * arraylist 如何去重
 * 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.contains(obj) 
			//如果不重复就往新容器里添加
			newal.add(obj);
		}
	}
	return newal;
}



}

结果:
在这里插入图片描述
②自定义对象去重

public class ArrayListdemo3 {
public static void main(String[] args) {
	ArrayList al = new ArrayList<>();
//	al.add("q");
//	al.add("w");
//	al.add("e");
//	al.add("r");
//	al.add("t");
//	al.add("t");
	al.add(new Person("q", 1));
	al.add(new Person("w", 2));
	al.add(new Person("e", 3));
	al.add(new Person("r", 4));
	al.add(new Person("t", 5));
	al.add(new Person("q", 1));
	al.add(new Person("w", 2));
	
	ArrayList newal=al;//建立新的容器容纳
	System.out.println("去重前容器大小:"+newal.size());
	newal=repeat(al);
	System.out.println("去重后容器大小:"+newal.size());
	
}
/**
 * arraylist 如何去重
 * 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.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();
	}
	/**
	 * 重写equals方法
	 */
	@Override
	public boolean equals(Object obj) {
		Person p = (Person) obj;
//		System.out.println(p.name+"---equals---"+this.name);
		return p.name.equals(this.name) && p.age == this.age;
	}
}

结果:
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值