JAVA基础——集合框架(二)List集合(Vector集合,ArrayList集合,LinkedList集合)各集合方法介绍,去除重复元素,栈堆模拟,foreach语句,数组转集合及集合转数组

一、 List集合特有的功能概述

因为List集合继承与Collection,所有有些方法类似。详细介绍一些List特有的功能。List也是一个接口。故不能新建对象,所以我们调用子类ArrayList

  • void add(int index,E element)
    在指定位置添加元素
List list =new ArrayList();
		list.add("a"); //从0开始
		list.add("b");
		list.add("c");
		list.add("d");
		list.add(1,"e");
		list.add(10,"f");//java.lang.IndexOutOfBoundsException,
//当存储时使用不存在的索引会存在数组越界。当然index可以小于等于size。
		System.out.println(list);

效果如下:
在这里插入图片描述
———————————————————————————————————————

  • E remove(int index)
    在指定位置删除元素
List list =new ArrayList();
	list.add("a");
	list.add("b");
	list.add("c");
	list.add("d");
	//记录被删除的元素
	Object obj  =list.remove(1);
	System.out.println(obj);
	System.out.println(list);

效果如下:
在这里插入图片描述
tips:remove方法传入的参数是索引,函数返回的是Object对象。
弊端:当我们传入的是数字的时候,他会把数字当成索引。

List list = new ArrayList();
		list.add(111);
		list.add(222);
		list.add(333);
		list.remove(111);	//删除的时候不会自动装箱,把111当作索引
		System.out.println(list);

效果如下:
在这里插入图片描述
———————————————————————————————————————

  • E get(int index)
    传入的参数是索引,我们可以通过索引获取单个元素。所以我们可以通过for循环来遍历List集合,这是List集合特有的遍历方式
List list =new ArrayList();
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("d");
		//Object object1 =list.get(0);
		//System.out.println(object1);
		for (int i = 0; i < list.size(); i++) {
    
    
			System.out.print(list.get(i));
		}

效果如下:
在这里插入图片描述
———————————————————————————————————————

  • E set(int index,E element)
    修改值,把指定位置的元素修改掉
List list =new ArrayList();
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("d");
		list.set(1, "z");
		System.out.println(list);

效果如下:
在这里插入图片描述

二、 List集合存储对象并遍历

在不传入泛型的情况下(需要进行向下转型,后面会引入泛型):

List list =new ArrayList();
		list.add(new Student("张三",12));//Object obj =new Student("张三",12);
		list.add(new Student("李四",13));
		list.add(new Student("王二",14));
		list.add(new Student("赵六",15));
		for (int i = 0; i < list.size(); i++) {
    
    
			//单纯的遍历
			System.out.println(list.get(i));		
			//通过索引获取每一个元素
			Student s = (Student) list.get(i);
			System.out.println(s.getName()+"       "+s.getAge());
		}

效果如下:
在这里插入图片描述

三、 集合框架(并发修改异常产生的原因及解决方案)

需求:我有一个集合,请问,我想判断里面有没有"world"这个元素,如果有,我就添加一个"javaee"元素,请写代码实现。

List list  =new ArrayList();
		list.add("a");
		list.add("b");
		list.add("world");
		list.add("c");
		list.add("d");
		list.add("e");
		Iterator it =list.iterator();
		while (it.hasNext()) {
    
    
//进行强转的原因是因为list添加进去的元素被提升为Object类型
			String str = (String) it.next();
			if ("world".equals(str)) {
    
    
				list.add("javaee");
			}
			System.out.println(list);
		}

效果如下:
在这里插入图片描述
此为并发修改异常当放大检测到对象的并发修改,但不允许这种修改时,抛出异常。也就是说,集合在添加的时候并没有告诉迭代器,将要添加数据,而是迭代器自主突然想要添加数据。遍历的同时也在增加元素。并发修改,进行了报错异常。
———————————————————————————————————————
解决方案
迭代器迭代元素,使用专门的迭代器添加元素(ListIterator()

List list  =new ArrayList();
		list.add("a");
		list.add("b");
		list.add("world");
		list.add("c");
		list.add("d");
		list.add("e");
		ListIterator lit =list.listIterator();		//List集合特有
		while (lit.hasNext()) {
    
    
			String str = (String)lit.next();
			if ("world".equals(str)) {
    
    
				lit.add("javaee");
			}
		}
 		System.out.println(list);
	}

效果如下:
在这里插入图片描述

四、 ListIterator介绍(了解即可)

  • boolean hasNext()是否有下一个
  • boolean hasPrevious()是否有前一个
  • Object next()返回下一个元素
  • Object previous();返回上一个元素
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");
		
		ListIterator lit = list.listIterator();			
//获取迭代器
		while(lit.hasNext()) {
    
    
			System.out.println(lit.next()); 			
//获取元素并将指针向后移动
		}
		
		System.out.println("-----------------");
		
		while(lit.hasPrevious()) {
    
    
			System.out.println(lit.previous()); 		
//获取元素并将指针向前移动
		}

如果我们注释hasNext()方法,那么hasPrevious(),什么也遍历不出。因为我们只有先执行hasNext()方法之后,指针才会往后移动。随后hasPrevious()才会调出结果。

五、Vector—— List下的Vector

Vector类特有功能

  • public void addElement(E obj)
  • public E elementAt(int index)
  • public Enumeration elements() //枚举
Vector v = new Vector();
		v.addElement("a");
		v.addElement("b");
		v.addElement("c");
		v.addElement("d");
		
		Enumeration en = v.elements();					
//获取枚举
		while(en.hasMoreElements()) {
    
    					
//判断集合中是否有元素
			System.out.println(en.nextElement());		
//获取集合中的元素
		}
	}

在这里插入图片描述

六、 ArrayList——去除ArrayList中重复字符串元素方式

  • 分析:
    `* 1.创建新集合
  • 2.根据传入的集合(老集合获取迭代器)
  • 3.遍历老集合
  • 4.通过新集合判断是否包含老集合的元素,如果包含就不添加,如果不包含就添加
public class Demo1_ArrayList {
    
    

	public static void main(String[] args) {
    
    
		// TODO Auto-generated method stub
		ArrayList list =new ArrayList();
		list.add("a");
		list.add("a");
		list.add("b");
		list.add("b");
		list.add("c");
		list.add("c");
		ArrayList newList=getSingle(list);
		System.out.println(newList);
	}
	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;
	}
}

效果如下:
在这里插入图片描述

七、ArrayList—— 去除ArrayList中重复自定义对象元素(重点)

案例:
第一步:新建Bean集合

public 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;
	}
	
	public Person(String name, int age) {
    
    
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
    
    
		return "Person [name=" + name + ", age=" + age + "]";
	}
	//注意该处重写了equals方法
	@Override
	public boolean equals(Object obj) {
    
    
		Person p =(Person)obj;
		return this.name.equals(p.name) &&this.age == p.age;
	}
	} 
public class Demo2_ArrayList {
    
    

	public static void main(String[] args) {
    
    
		// TODO Auto-generated method stub
		ArrayList list =new ArrayList();			
//创建集合对象
		list.add(new Person("张三",12));
		list.add(new Person("张三",12));
		list.add(new Person("李四",13));
		list.add(new Person("李四",13));
		list.add(new Person("李四",13));
		list.add(new Person("李四",13));
		
		ArrayList newList =getSingle(list);			
		//调用方法去除重复
		System.out.println(newList);
	}
	public static ArrayList getSingle(ArrayList list) {
    
    			
		ArrayList newList =new ArrayList();			
//创建新集合
		Iterator it =list.iterator();				
//根据传入的集合(老集合)获取迭代器	
		while (it.hasNext()) {
    
    						
//遍历老集合
			Object object =it.next();				
//记录住每一个元素
			if (!newList.contains(object)) {
    
    				
//如果新集合中不包含老集合中的元素
					newList.add(object)	;							//将该元素添加
			}
		}
		return newList;
	}
}

效果如下:
在这里插入图片描述

tips:注意该处
重写了父类的equals。因为父类中的方法的contains方法,里面进行判断用的是equals()方法,我们需要进行修改。当然如果我们调用remove()方法,依旧依赖于equals()方法,进行包含判断。

八、 LinkedList——LinkedList的特有功能

  • public void addFirst(E e)及addLast(E e)
    addFirst()是在数组的头部添加,addLast()是在数组的尾部添加。
LinkedList list =new LinkedList();
		list.addFirst("a");
		list.addFirst("b");
		list.addFirst("c");
		list.addFirst("d");
		
		list.addLast("e");
		System.out.println(list);

效果如下:
在这里插入图片描述
———————————————————————————————————————

  • public E getFirst()及getLast()
    getFirst()获得第一个元素,getLast()获得最后一个元素
LinkedList list =new LinkedList();
		list.addFirst("a");
		list.addFirst("b");
		list.addFirst("c");
		list.addFirst("d");
		list.addLast("e");
		System.out.println(list);
		System.out.print("第一个是");
		System.out.println(list.getFirst());
		System.out.print("最后一个是");
		System.out.println(list.getLast());

效果如下:
在这里插入图片描述
———————————————————————————————————————

  • public E removeFirst()及public E removeLast()
    removeFirst()删除第一个元素,removeLast删除最后一个元素
LinkedList list =new LinkedList();
		list.addFirst("a");
		list.addFirst("b");
		list.addFirst("c");
		list.addFirst("d");	
		list.addLast("e");
		System.out.print("删除第一个元素");
		System.out.println(list.removeFirst());
		System.out.print("删除第一个元素");
		System.out.println(list.removeLast());
		System.out.println(list);

效果如下:
在这里插入图片描述
———————————————————————————————————————

  • public E get(int index);
    参数传入的是索引,可以通过索引找出数
LinkedList list =new LinkedList();
		list.addFirst("a");
		list.addFirst("b");
		list.addFirst("c");
		list.addFirst("d");	
		list.addLast("e");
		System.out.println(list.get(1));

效果如下:
在这里插入图片描述
———————————————————————————————————————

九、 用LinkedList模拟栈数据结构的集合并测试(重点)

分析我们使用LinkedList中的addLast()方法模拟进栈,removeLast()模拟出栈。因为我们是模拟栈,所以最好使用一个类,把LinkedList封装到类中,类的名字为栈。

public class Stack {
    
    
	private LinkedList list =new LinkedList(); 
	//模拟进栈方法
	public void in(Object obj) {
    
    
		list.addLast(obj);
	}
	
	//模拟出栈
	public Object out() {
    
    
		return list.removeLast();
	}
	
	//模拟栈结构是否为空
	public boolean isEmpty() {
    
    
		return list.isEmpty();
	}
}

调用调试:

Stack stack = new Stack();
	stack.in("a");
	stack.in("b");
	stack.in("c");
	stack.in("d");
	while (!stack.isEmpty()) {
    
    
		System.out.println(stack.out());	
	}

在此基础上我们会可以模拟队列,队列是先进先出,只要修改removeLast()改为removeFirst()

十、 List三个子类的特点

ArrayList:
底层数据结构是数组,查询快,增删慢。
线程不安全,效率高。
Vector:
底层数据结构是数组,查询快,增删慢。
线程安全,效率低。
Vector相对ArrayList查询慢(线程安全的)
Vector相对LinkedList增删慢(数组结构)
LinkedList:
底层数据结构是链表,查询慢,增删快。
线程不安全,效率高。
Vector和ArrayList的区别
Vector是线程安全的,效率低
ArrayList是线程不安全的,效率高
共同点:都是数组实现的
ArrayList和LinkedList的区别
ArrayList底层是数组结果,查询和修改快
LinkedList底层是链表结构的,增和删比较快,查询和修改比较慢
共同点:都是线程不安全的
List有三个儿子,我们到底使用谁呢?
查询多用ArrayList
增删多用LinkedList
如果都多ArrayList

Vector面试的时候用,其已经被ArrayList代替。线程安全一般用vector但是后面会使用工具类,把线程不安全的数组改成线程安全的。所以Vector用的比较少。

十一、 增强for(For-Each)的概述和使用

增强for概述
简化数组和Collection集合的遍历
格式

for(元素数据类型 变量 : 数组或者Collection集合) {
    
    
			使用变量即可,该变量就是元素
		}

当我们遍历数组和集合

int arr[] = {
    
    11,22,33,44,55,66};
	List<String> list =new ArrayList<String>();
	list.add("a");
	list.add("b");
	list.add("c");
	list.add("d");
	for (String string : list) {
    
    
		System.out.print(string);
		
	}
	System.out.println();
	for (int i : arr) {
    
    
		System.out.print(i);
	}

当我们遍历对象的时候

List<Person> list =new ArrayList<Person>();
		list.add(new Person("张三 ", 12));
		list.add(new Person("李四 ", 13));
		list.add(new Person("王五 ", 14));
		for (Person person : list) {
    
    
			System.out.println(person);
		}

增强for循环底层依赖的是迭代器(Iterator)

十二、 三种迭代的能否删除

普通for循环

List<String> list =new ArrayList<String>();
		list.add("a");
		list.add("b");
		list.add("b");
		list.add("c");
		list.add("b");
		list.add("d");
		//1.普通for循环删除
		for (int i = 0; i < list.size(); i++) {
    
    
			if ("b".equals(list.get(i))) {
    
    
				list.remove(i--);			
//通过索引删除元素,应该改为remove(i--)使元素往后移动一位
			}
		}
	System.out.println(list);

效果如下:
在这里插入图片描述
———————————————————————————————————————
迭代器删除

//方法一:
		Iterator<String> iterator =list.iterator();
		while (iterator.hasNext()) {
    
    
			if ("b".equals(iterator.next())) {
    
    
				//list.remove("b");
//不能用集合的删除方法,因为迭代过程中如果集合修改会出现并发修改异常
				iterator.remove();
			}
			
		}
		//方法二:
		for (Iterator<String> iterator2 =list.iterator();iterator2.hasNext();  ) {
    
    
			if ("b".equals(iterator.next())) {
    
    
				//list.remove("b");
	//不能用集合的删除方法,因为迭代过程中如果集合修改会出现并发修改异常
				iterator.remove();
			}
		}
		System.out.println(list);

tips:以上为两种不同的写法,并非不同的方法。
———————————————————————————————————————
增强for循环
该方法不能删除 只能遍历;

十三、 数组转集合以及集合转数组

数组转集合方法:Arrays工具类的asList()方法的使用
该方法用于将数组转换为集合,但是不能进行集合的增加和删除元素操作,但是可以运行一些迭代器进行遍历挑选。

String [] arr= {
    
    "a","b","c"};
		List<String> list = Arrays.asList(arr);
		list.add("d"); 							
//该处不能添加
		System.out.println(list);

//报错
———————————————————————————————————————
当我们存储一些int类型的基本类型数据的时候,将整个数组当成一个对象存储在集合中
注意该泛型应该是一个int型的数组

int [] arr= {
    
    11,22,33,44,55};
		List<int []> list =Arrays.asList(arr);
		//
		System.out.println(list);

效果如下:
在这里插入图片描述
处理方法:

Integer[ ] arr= {
    
    11,22,33,44,55};
//数组必须是引用基本类型
		List<Integer > list =Arrays.asList(arr);
		System.out.println(list);

集合转数组方法
Collection中toArray(T[] a)泛型版的集合转数组

ArrayList<String> list =new ArrayList<String>();
		list.add("a");
		list.add("b");
		list.add("c");
		list.add("d");
		String[] arr=list.toArray(new String[0]);
//后面数组的0,当集合转换为数组时
//数组的长度如果是小于等于集合的size()时,转换后的数组长度等于集合size()
//如果数组长度大于集合长度,那么会输出null
		for (String string : arr) {
    
    
			System.out.println(string);
		}

效果如下:
在这里插入图片描述

———————————————————————————————————————

十四、 集合嵌套之ArrayList嵌套ArrayList

学科为大集合,学科又分为若干个班级

ArrayList<ArrayList<Person>> list =new ArrayList<ArrayList<Person>>();
		ArrayList<Person> list1  = new ArrayList<Person>();
		list1.add(new Person("小明",12));
		list1.add(new Person("小红",13));
		
		ArrayList<Person> list2  = new ArrayList<Person>();
		list2.add(new Person("张三",14));
		list2.add(new Person("李四",15));
		
		list.add(list1);
		list.add(list2);
		//遍历学科集合
		for (ArrayList<Person> A : list) {
    
    
			for (Person person : A) {
    
    
				System.out.println(person);
			}
		}

效果如下:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Mr_GYF/article/details/108677192