Day16-集合(上)List、Set、迭代器、泛型、比较器


集合

一、概念

含义:一组数据的容器,跟数组类似

二、特点

  1. 集合是Java API所提供的一系列类,可以用于动态存放多个对象。–集合只能存对象
  2. 集合与数组的不同在于,集合是大小可变的序列,而且元素类型可以不受限定,只要是引用类型。(集合中不能放基本数据类型,但可以放基本数据类型的包装类)
  3. 集合类全部支持泛型,是一种数据安全的用法。

三、集合 vs 数组

数组:一旦初始化,长度不可变;可以存放基本数据类型;元素类型必须和数组声明时的类型兼容

集合:长度可变的序列;只能存放引用数据类型;元素类型不受限定

四、集合家族

Collection家族 – 接口

提供了基本的增删改查的功能
在这里插入图片描述

List家族 – 接口

特点:有序的,且可重复的(添加了很多针对下标操作的方法)

实现类:

  1. ArrayList

    数据结构:一维数组

package com.dream.arraylist_class;

import java.util.ArrayList;

public class Test01 {
	
	public static void main(String[] args) {
		/**
		 * 初识ArrayList
		 */
		
		//创建集合对象
		ArrayList list = new ArrayList();
		
		//添加元素
		list.add("abc");
		list.add("abc");
		list.add(123);//Integer.valueOf(123)
		list.add(123);//Integer.valueOf(123)
		list.add(1.23);//Double.valueOf(1.23)
		list.add(1.23);//Double.valueOf(1.23)
		
		//获取长度
		System.out.println("获取集合中元素的个数:" + list.size());	
		
	}

}

package com.dream.arraylist_class;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.function.Predicate;

public class Test02 {

	public static void main(String[] args) {
		/**
		 * 使用ArrayList常用方法
		 */

		//创建集合对象 - 泛型规定该集合只能存储String类型的数据
		ArrayList<String> list = new ArrayList<>();

		//添加元素
		list.add("麻生希");
		list.add("椎名空");
		list.add("三上悠亚");
		list.add("深田咏美");
		list.add("波多野结衣");
		list.add("明日花绮罗");
		list.add("铃原爱蜜莉");
		list.add("小西满里惠");
		list.add("杨晨");
		list.add("陈希");

		//往指定的下标上插入元素
		list.add(2, "北条麻衣");

		//添加集合
		//		ArrayList<String> newList1 = new ArrayList<>();
		//		Collections.addAll(newList1, "aaa","bbb","ccc","ddd");//使用集合工具类批量添加元素
		//		list.addAll(newList1);//把newList1集合中所有的元素添加到list集合中

		//在指定下标上添加集合
		ArrayList<String> newList1 = new ArrayList<>();
		Collections.addAll(newList1, "aaa","bbb","ccc","ddd");//使用集合工具类批量添加元素
		list.addAll(2, newList1);//在指定下标把newList1集合中所有的元素添加到list集合中

		//删除
		list.remove(4);//根据下标删除元素
		list.remove("ddd");//根据元素删除元素
		list.removeIf(new Predicate<String>() {//根据条件删除元素
			@Override
			public boolean test(String t) {
				if(t.length() >= 5){
					return true;
				}
				return false;
			}
		});

		//删除交集
		ArrayList<String> newList2 = new ArrayList<>();
		Collections.addAll(newList2, "aaa","xxx","yyy");
		list.removeAll(newList2);

		//设置指定下标上的元素
		list.set(1, "爱田奈奈");

		//保留交集
		ArrayList<String> newList3 = new ArrayList<>();
		Collections.addAll(newList3, "bbb","北条麻衣","yyy","杨晨","陈希");
		list.retainAll(newList3);

		//获取指定下标上的元素
		System.out.println("获取指定下标上的元素:" + list.get(1));

		//获取长度
		System.out.println("获取集合中元素的个数:" + list.size());

		//清空集合中所有的元素
		//list.clear();

		System.out.println("查询集合中是否包含某个元素:" + list.contains("aaa"));
		System.out.println("查询该元素在集合中的下标:" + list.indexOf("aaa"));
		System.out.println("判断该集合中是否没有元素:" + list.isEmpty());//没有元素-true 有元素-false

		//获取指定下标区间的元素
		List<String> newList4 = list.subList(1, 3);
		System.out.println(Arrays.toString(newList4.toArray()));//集合->数组->字符串
		
		System.out.println("---------------------------");

		//遍历集合

		//1.for循环
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}
		System.out.println("---------------------------");
		
		//2.foreach
		for (String e : list) {
			System.out.println(e);
		}
		
		System.out.println("---------------------------");
		
		//3.Iterator
		Iterator<String> it = list.iterator();
		while(it.hasNext()){//判断是否有可迭代的数据
			String next = it.next();//返回下一个数据
			System.out.println(next);
		}
		
		System.out.println("---------------------------");
		
		//4.ListIterator
		ListIterator<String> listIterator = list.listIterator();
		while(listIterator.hasNext()){//判断是否有可迭代的数据
			String next = listIterator.next();//返回下一个数据
			System.out.println(next);
		}
	}
}

  1. LinkedList

    数据结构:双向链表

package com.dream.linkedlist_class;

import java.util.LinkedList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.function.Predicate;

public class Test01 {

	public static void main(String[] args) {
		/**
		 * 使用LinkedList常用方法
		 */

		//创建集合对象 - 泛型规定该集合只能存储String类型的数据
		LinkedList<String> list = new LinkedList<>();

		//添加元素
		list.add("麻生希");
		list.add("椎名空");
		list.add("三上悠亚");
		list.add("深田咏美");
		list.add("波多野结衣");
		list.add("明日花绮罗");
		list.add("铃原爱蜜莉");
		list.add("小西满里惠");
		list.add("杨晨");
		list.add("陈希");

		//往指定的下标上插入元素
		list.add(2, "北条麻衣");

		//添加集合
		//		LinkedList<String> newList1 = new LinkedList<>();
		//		Collections.addAll(newList1, "aaa","bbb","ccc","ddd");//使用集合工具类批量添加元素
		//		list.addAll(newList1);//把newList1集合中所有的元素添加到list集合中

		//在指定下标上添加集合
		LinkedList<String> newList1 = new LinkedList<>();
		Collections.addAll(newList1, "aaa","bbb","ccc","ddd");//使用集合工具类批量添加元素
		list.addAll(2, newList1);//在指定下标把newList1集合中所有的元素添加到list集合中

		//删除
		list.remove(4);//根据下标删除元素
		list.remove("ddd");//根据元素删除元素
		list.removeIf(new Predicate<String>() {//根据条件删除元素
			@Override
			public boolean test(String t) {
				if(t.length() >= 5){
					return true;
				}
				return false;
			}
		});

		//删除交集
		LinkedList<String> newList2 = new LinkedList<>();
		Collections.addAll(newList2, "aaa","xxx","yyy");
		list.removeAll(newList2);

		//设置指定下标上的元素
		list.set(1, "爱田奈奈");

		//保留交集
		LinkedList<String> newList3 = new LinkedList<>();
		Collections.addAll(newList3, "bbb","北条麻衣","yyy","杨晨","陈希");
		list.retainAll(newList3);

		//获取指定下标上的元素
		System.out.println("获取指定下标上的元素:" + list.get(1));

		//获取长度
		System.out.println("获取集合中元素的个数:" + list.size());

		//清空集合中所有的元素
		//list.clear();

		System.out.println("查询集合中是否包含某个元素:" + list.contains("aaa"));
		System.out.println("查询该元素在集合中的下标:" + list.indexOf("aaa"));
		System.out.println("判断该集合中是否没有元素:" + list.isEmpty());//没有元素-true 有元素-false

		//获取指定下标区间的元素
		List<String> newList4 = list.subList(1, 3);
		System.out.println(Arrays.toString(newList4.toArray()));//集合->数组->字符串
		
		System.out.println("---------------------------");

		//遍历集合

		//1.for循环
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}
		System.out.println("---------------------------");
		
		//2.foreach
		for (String e : list) {
			System.out.println(e);
		}
		
		System.out.println("---------------------------");
		
		//3.Iterator
		Iterator<String> it = list.iterator();
		while(it.hasNext()){//判断是否有可迭代的数据
			String next = it.next();//返回下一个数据
			System.out.println(next);
		}
		
		System.out.println("---------------------------");
		
		//4.ListIterator
		ListIterator<String> listIterator = list.listIterator();
		while(listIterator.hasNext()){//判断是否有可迭代的数据
			String next = listIterator.next();//返回下一个数据
			System.out.println(next);
		}
	}
}

package com.dream.linkedlist_class;

import java.util.LinkedList;

public class Test02 {
	
	public static void main(String[] args) {
		/**
		 * LinkedList 队列模式
		 * 
		 * 特点:先进先出
		 */
		
		LinkedList<Integer> list = new LinkedList<>();
		
		list.add(1);
		list.add(2);
		list.add(3);
		list.add(4);
		list.add(5);
		
		while(!list.isEmpty()){
			Integer first = list.removeFirst();//删除第一个元素,并返回
			System.out.println(first);
		}
		
		System.out.println("集合中元素的个数为:" + list.size());//0
	}

}

package com.dream.linkedlist_class;

import java.util.LinkedList;

public class Test03 {
	
	public static void main(String[] args) {
		/**
		 * LinkedList 栈模式
		 * 
		 * 特点:先进后出
		 */
		
		LinkedList<Integer> list = new LinkedList<>();
		
		list.add(1);
		list.add(2);
		list.add(3);
		list.add(4);
		list.add(5);
		
		while(!list.isEmpty()){
			Integer last = list.removeLast();//删除最后一个元素,并返回
			System.out.println(last);
		}
		
		System.out.println("集合中元素的个数为:" + list.size());//0
	}

}

  1. Vector

    数据结构:一维数组

package com.dream.vector_class;

import java.util.Iterator;
import java.util.Vector;

public class Test01 {
	
	public static void main(String[] args) {
		/**
		 * Vector 新方法
		 */
		
		Vector<String> v = new Vector<>();
		
		v.add("小红");
		v.add("小绿");
		v.add("小黄");

		Iterator<String> it = v.iterator();
		while (it.hasNext()) {
			String string = it.next();
			System.out.println(string);
		}
	}

}

package com.dream.vector_class;

import java.util.Enumeration;
import java.util.Vector;

public class Test02 {
	
	public static void main(String[] args) {
		/**
		 * Vector 老方法
		 */
		
		Vector<String> v = new Vector<>();
		
		v.addElement("小红");
		v.addElement("小绿");
		v.addElement("小黄");

		Enumeration<String> elements = v.elements();
		while(elements.hasMoreElements()){
			String nextElement = elements.nextElement();
			System.out.println(nextElement);
		}
	}

}

  1. Stack (extends Vector)

    数据结构:一维数组

package com.dream.stack_class;

import java.util.Stack;

public class Test01 {
	
	public static void main(String[] args) {
		/**
		 * Stack 
		 * 特点:栈模式(先进后出)
		 */
		
		Stack<Integer> stack = new Stack<>();
		
		//把元素压入栈顶
		stack.push(1);
		stack.push(2);
		stack.push(3);
		stack.push(4);
		stack.push(5);
		
		System.out.println("返回一个对象在此堆栈上的基于1的位置:" + stack.search(1));
		
		while(!stack.empty()){
			Integer pop = stack.pop();
			System.out.println(pop);
		}
		
		System.out.println("集合中元素的个数为:" + stack.size());
		
		
	}
}

Set家族 – 接口

特点:无序的,且不可重复的

实现类:

  1. HashSet

    数据结构:hash数组

package com.dream.hashset_class;

import java.util.HashSet;
import java.util.Collections;
import java.util.Iterator;
import java.util.function.Predicate;

public class Test01 {

	public static void main(String[] args) {
		/**
		 * 使用HashSet常用方法
		 */

		//创建集合对象 - 泛型规定该集合只能存储String类型的数据
		HashSet<String> set = new HashSet<>();

		//添加元素
		set.add("麻生希");
		set.add("椎名空");
		set.add("三上悠亚");
		set.add("深田咏美");
		set.add("波多野结衣");
		set.add("明日花绮罗");
		set.add("铃原爱蜜莉");
		set.add("小西满里惠");
		set.add("杨晨");
		set.add("陈希");

		//添加集合
		HashSet<String> newSet1 = new HashSet<>();
		Collections.addAll(newSet1, "aaa","bbb","ccc","ddd");//使用集合工具类批量添加元素
		set.addAll(newSet1);//把newSet1集合中所有的元素添加到set集合中

		//删除
		set.remove("ddd");//根据元素删除元素
		set.removeIf(new Predicate<String>() {//根据条件删除元素
			@Override
			public boolean test(String t) {
				if(t.length() >= 5){
					return true;
				}
				return false;
			}
		});

		//删除交集
		HashSet<String> newSet2 = new HashSet<>();
		Collections.addAll(newSet2, "aaa","xxx","yyy");
		set.removeAll(newSet2);

		//保留交集
		HashSet<String> newSet3 = new HashSet<>();
		Collections.addAll(newSet3, "bbb","北条麻衣","yyy","杨晨","陈希");
		set.retainAll(newSet3);

		//获取长度
		System.out.println("获取集合中元素的个数:" + set.size());

		//清空集合中所有的元素
		//set.clear();

		System.out.println("查询集合中是否包含某个元素:" + set.contains("aaa"));
		System.out.println("判断该集合中是否没有元素:" + set.isEmpty());//没有元素-true 有元素-false

		System.out.println("---------------------------");

		//遍历集合

		//1.foreach
		for (String e : set) {
			System.out.println(e);
		}

		System.out.println("---------------------------");

		//2.Iterator
		Iterator<String> it = set.iterator();
		while(it.hasNext()){//判断是否有可迭代的数据
			String next = it.next();//返回下一个数据
			System.out.println(next);
		}

	}
}

package com.dream.hashset_class;

import java.util.HashSet;

public class Test02 {

	public static void main(String[] args) {
		/**
		 * 理解HashSet 无序且不可重复
		 * 
		 * 存入顺序:
		 * 	1.获取对象的hash码 -- hashCode
		 * 	2.hash码 + 散列算法 获得在数组中的下标
		 * 	3.判断该下标上是否有元素
		 * 		没有 - 直接放入
		 * 		有  -- 判断两个对象是否一样
		 * 
		 * 取出顺序:按照数组从头到尾
		 */
		
		HashSet<Integer> set = new HashSet<>();
		
		set.add(11);//Integer.valueOf(11)
		set.add(22);//Integer.valueOf(22)
		set.add(33);//Integer.valueOf(33)
		set.add(44);//Integer.valueOf(44)
		set.add(44);//Integer.valueOf(44)
		
		for (Integer integer : set) {
			System.out.println(integer);
		}
		
	}
}

  1. LinkedHashSet (extends HashSet)

    概念: LinkedHashSet继承自HashSet,HashSet存入的元素是不可重复的,无序的。与HashSet相比,LinkedHashSet源码更少、更简单,唯一的区别是LinkedHashSet内部使用的是LinkedHashMap。这样做的意义或者好处就是LinkedHashSet中的元素顺序是可以保证的,也就是说遍历序和插入序是一致的。

特点: 1、底层是一种链接列表和哈希表组成
2、可以保证元素的唯一性,是由哈希表决定的(hashCode()和equals())
3、可以保证元素的迭代顺序一致(有序),存储和取出一致,是由链表决定

场合: 什么时候使用LinkedHashSet集合?
如果在开发中,元素唯一性,并且还要保证元素有序(存储和取出一致),使用LinkedHashSet集合。

package com.dream.linkedhashset_class;

import java.util.LinkedHashSet;
import java.util.Collections;
import java.util.Iterator;
import java.util.function.Predicate;

public class Test01 {

	public static void main(String[] args) {
		/**
		 * 使用LinkedHashSet常用方法
		 */

		//创建集合对象 - 泛型规定该集合只能存储String类型的数据
		LinkedHashSet<String> set = new LinkedHashSet<>();

		//添加元素
		set.add("麻生希");
		set.add("椎名空");
		set.add("三上悠亚");
		set.add("深田咏美");
		set.add("波多野结衣");
		set.add("明日花绮罗");
		set.add("铃原爱蜜莉");
		set.add("小西满里惠");
		set.add("杨晨");
		set.add("陈希");

		//添加集合
		LinkedHashSet<String> newSet1 = new LinkedHashSet<>();
		Collections.addAll(newSet1, "aaa","bbb","ccc","ddd");//使用集合工具类批量添加元素
		set.addAll(newSet1);//把newSet1集合中所有的元素添加到set集合中

		//删除
		set.remove("ddd");//根据元素删除元素
		set.removeIf(new Predicate<String>() {//根据条件删除元素
			@Override
			public boolean test(String t) {
				if(t.length() >= 5){
					return true;
				}
				return false;
			}
		});

		//删除交集
		LinkedHashSet<String> newSet2 = new LinkedHashSet<>();
		Collections.addAll(newSet2, "aaa","xxx","yyy");
		set.removeAll(newSet2);

		//保留交集
		LinkedHashSet<String> newSet3 = new LinkedHashSet<>();
		Collections.addAll(newSet3, "bbb","北条麻衣","yyy","杨晨","陈希");
		set.retainAll(newSet3);

		//获取长度
		System.out.println("获取集合中元素的个数:" + set.size());

		//清空集合中所有的元素
		//set.clear();

		System.out.println("查询集合中是否包含某个元素:" + set.contains("aaa"));
		System.out.println("判断该集合中是否没有元素:" + set.isEmpty());//没有元素-true 有元素-false

		System.out.println("---------------------------");

		//遍历集合

		//1.foreach
		for (String e : set) {
			System.out.println(e);
		}

		System.out.println("---------------------------");

		//2.Iterator
		Iterator<String> it = set.iterator();
		while(it.hasNext()){//判断是否有可迭代的数据
			String next = it.next();//返回下一个数据
			System.out.println(next);
		}

	}
}

package com.dream.linkedhashset_class;

import java.util.LinkedHashSet;

public class Test02 {

	public static void main(String[] args) {
		/**
		 * 做实验证明LinkedLinkedHashSet有序的
		 */
		
		LinkedHashSet<Integer> set = new LinkedHashSet<>();
		
		set.add(11);//Integer.valueOf(11)
		set.add(22);//Integer.valueOf(22)
		set.add(33);//Integer.valueOf(33)
		set.add(44);//Integer.valueOf(44)
		set.add(44);//Integer.valueOf(44)
		
		for (Integer integer : set) {
			System.out.println(integer);
		}
		
	}
}

  1. TreeSet

    数据结构:二叉树

package com.dream.treeset_class;

import java.util.Iterator;
import java.util.TreeSet;

public class Test01 {
	
	public static void main(String[] args) {
		/**
		 * 做实验证明TreeSet 自然排序
		 * 自然排序:根据不同类型,选择不同排序规则
		 * 
		 * TreeSet存储Integer类型:数字升序
		 */
		
		TreeSet<Integer> set = new TreeSet<>();
		
		set.add(4);
		set.add(1);
		set.add(6);
		set.add(3);
		set.add(5);
		set.add(2);
		set.add(2);

		Iterator<Integer> it = set.iterator();
		while (it.hasNext()) {
			Integer integer = it.next();
			System.out.println(integer);
		}
	}

}

package com.dream.treeset_class;

import java.util.Iterator;
import java.util.TreeSet;

public class Test02 {
	
	public static void main(String[] args) {
		/**
		 * 做实验证明TreeSet 自然排序
		 * 自然排序:根据不同类型,选择不同排序规则
		 * 
		 * TreeSet存储String类型:字典排序
		 */
		
		TreeSet<String> set = new TreeSet<>();
		
		set.add("b");
		set.add("d");
		set.add("a");
		set.add("c");
		set.add("c");

		Iterator<String> it = set.iterator();
		while (it.hasNext()) {
			String string = it.next();
			System.out.println(string);
		}
	}

}

package com.dream.treeset_class;

import java.util.TreeSet;

public class Test03 {
	
	public static void main(String[] args) {
		/**
		 * 做实验 学习内置比较器(比较接口)
		 */
	
		TreeSet<Student> set = new TreeSet<>();
		
		set.add(new Student("麻生希", '女', 28, "2101", "001"));
		set.add(new Student("椎名空", '女', 23, "2101", "002"));
		set.add(new Student("北岛玲", '女', 27, "2101", "003")	);
		set.add(new Student("水野朝阳", '女', 31, "2101", "004"));
		set.add(new Student("三上悠亚", '女', 26, "2101", "005"));
		set.add(new Student("濑亚美莉", '女', 32, "2101", "006"));
		set.add(new Student("爱田奈奈", '女', 36, "2102", "001"));
		set.add(new Student("深田咏美", '女', 28, "2102", "002"));
		set.add(new Student("小西满里惠", '女', 28, "2102", "003"));
		set.add(new Student("桃谷绘里香", '女', 29, "2102", "004"));
		set.add(new Student("明日花绮罗", '女', 29, "2102", "005"));
		set.add(new Student("铃原爱蜜莉", '女', 29, "2102", "006"));
		set.add(new Student("波多野结衣", '女', 34, "2102", "007"));
		
		for (Student stu : set) {
			System.out.println(stu);
		}
	}           

}

Map家族

下章学习

特点:键值对存储

实现类:

  1. HashMap

    特点:key是唯一的


  1. LinkedHashMap

  2. Hashtable

  3. ConcurrentHashMap

  4. TreeMap

  5. Properties

五、迭代器

分类:Iterator、ListIterator

理解:迭代器中使用集合删除元素会报错的原因(modCount != expectedModCount)

注意:
(1)Iterator只能单向移动。
(2)Iterator.remove()是唯一安全的方式来在迭代过程中修改集合;如果在迭代过程中以任何其它的方式修改了基本集合将会产生未知的行为。而且每调用一次next()方 法,remove()方法只能被调用一次,如果违反这个规则将抛出一个异常。

Iterator vs ListIterator

Iterator :遍历集合、删除元素
概念: Iterator是一个接口,它是集合的迭代器,集合可以通过Iterator去遍历集合中的元素,常用API接口

hasNext():如果迭代器中还有元素,则返回true.
next():返回迭代器中的下一个元素
remove():删除迭代器新返回的元素。

package com.dream.iterator;

import java.util.ArrayList;
import java.util.Iterator;

public class Test01 {

	public static void main(String[] args) {
		/**
		 * 研究Iterator
		 * 
		 * 需求:遍历集合,在Iterator中删除元素
		 * 
		 * 注意:foreach底层由迭代器实现
		 */
		
		ArrayList<String> list = new ArrayList<>();
		
		list.add("aaa");
		list.add("bbb");
		list.add("ccc");
		list.add("ddd");
		list.add("eee");
		
		//遍历到ccc时,删除元素
		Iterator<String> it = list.iterator();
		while(it.hasNext()){
			String element = it.next();
			if(element.equals("ccc")){
				it.remove();
			}
		}
		
		//遍历输出
		for (String e : list) {
			System.out.println(e);
		}
	}
}

ListIterator:只能List接口下的实现类调用,遍历集合、删除元素、添加元素、替换元素、指定下标开始遍历元素、倒叙遍历

ListIterator的功能更加强大, 它继承于Iterator接口,只能用于各种List类型的访问。可以通过调用listIterator()方法产生一个指向List开始处的ListIterator, 还可以调用listIterator(n)方法创建一个一开始就指向列表索引为n的元素处的ListIterator,汉化API如下:
1. boolean hasNext);如果在正向遍历时,这个列表迭代器有更多元素,返回true。
2. E next();返回正向遍历到的元素。
3. boolean hasPrevious);如果在反向遍历时,这个列表迭代器有更多元素,返回true.
4. E previous();返回反向遍历到的元素。
5. int nextIndex();返回后续调用next将返回的元素索引,最后一次返回列表大小。
6. int previousIndex(0;返回后续调用previous将返回的元素的索引,最后一-次返回-1。
7. void remove0;删除调用next或previous返回的元素,只有在调用next或previous之 后为调用add才能进行操作。
8. void set(E e);用指定的元素替换遍历到的元素。
9. void add(E e);将指定元素插入到遍历到的元素左边(next之前、 previous之后) 。

由此我们可以推断出ListIterator可以:
(1)双向移动(向前/向后遍历).
(2)产生相对于迭代器在列表中指向的当前位置的前一个和后一个元素的索引.
(3)可以使用set()方法替换它访问过的最后一个元素.
(4)可以使用add()方法在next()方法返回的元素之前或previous()方法返回的元素之后插入一个元素.
package com.dream.iterator;

import java.util.ArrayList;
import java.util.ListIterator;

public class Test02 {

	public static void main(String[] args) {
		/**
		 * 研究ListIterator
		 * 
		 * 需求:遍历集合,在ListIterator中删除元素
		 */
		
		ArrayList<String> list = new ArrayList<>();
		
		list.add("aaa");
		list.add("bbb");
		list.add("ccc");
		list.add("ddd");
		list.add("eee");
		
		//遍历到ccc时,删除元素
		ListIterator<String> it = list.listIterator();
		while(it.hasNext()){
			String next = it.next();
			if(next.equals("ccc")){
				it.remove();
			}
		}
		
		//遍历输出
		for (String e : list) {
			System.out.println(e);
		}
	}
}

package com.dream.iterator;

import java.util.ArrayList;
import java.util.ListIterator;

public class Test03 {

	public static void main(String[] args) {
		/**
		 * 研究ListIterator
		 * 
		 * 需求:遍历集合,在ListIterator中添加元素
		 */
		
		ArrayList<String> list = new ArrayList<>();
		
		list.add("aaa");
		list.add("bbb");
		list.add("ccc");
		list.add("ddd");
		list.add("eee");
		
		//遍历到ccc时,添加元素
		ListIterator<String> it = list.listIterator();
		while(it.hasNext()){
			String next = it.next();
			if(next.equals("ccc")){
				it.add("杨晨");
			}
		}
		
		//遍历输出
		for (String e : list) {
			System.out.println(e);
		}
	}
}

package com.dream.iterator;

import java.util.ArrayList;
import java.util.ListIterator;

public class Test04 {

	public static void main(String[] args) {
		/**
		 * 研究ListIterator
		 * 
		 * 需求:遍历集合,在ListIterator中替换元素
		 */
		
		ArrayList<String> list = new ArrayList<>();
		
		list.add("aaa");
		list.add("bbb");
		list.add("ccc");
		list.add("ddd");
		list.add("eee");
		
		//遍历到ccc时,替换元素
		ListIterator<String> it = list.listIterator();
		while(it.hasNext()){
			String next = it.next();
			if(next.equals("ccc")){
				it.set("杨晨");
			}
		}
		
		//遍历输出
		for (String e : list) {
			System.out.println(e);
		}
	}
}

package com.dream.iterator;

import java.util.ArrayList;
import java.util.ListIterator;

public class Test05 {

	public static void main(String[] args) {
		/**
		 * 研究ListIterator
		 * 
		 * 需求:指定下标遍历集合
		 */
		
		ArrayList<String> list = new ArrayList<>();
		
		list.add("aaa");
		list.add("bbb");
		list.add("ccc");
		list.add("ddd");
		list.add("eee");
		
		//指定下标遍历集合
		ListIterator<String> it = list.listIterator(2);
		while (it.hasNext()) {
			String e = it.next();
			System.out.println(e);
			
		}
	}
}

package com.dream.iterator;

import java.util.ArrayList;
import java.util.ListIterator;

public class Test06 {

	public static void main(String[] args) {
		/**
		 * 研究ListIterator
		 * 
		 * 需求:倒叙遍历集合
		 */
		
		ArrayList<String> list = new ArrayList<>();
		
		list.add("aaa");
		list.add("bbb");
		list.add("ccc");
		list.add("ddd");
		list.add("eee");
		
		//指定下标遍历集合
		ListIterator<String> it = list.listIterator(list.size());
		while(it.hasPrevious()){
			String e = it.previous();
			System.out.println(e);
		}
	}
}

六、泛型限定

JDK1.4以前:
1、 装入集合的数据都会被当作Object对象来存放,从而失去了自己的实际类型。
2、 从集合中取出元素时,需要进行强制类型转换。效率低,容易产生错误。
从JDK1.5开始,sun公司推出了泛型来解决上述问题:
1、在定义一个集合时就指定集合存储的对象的数据类型
如:Collection coll = new ArrayList();
3、 存入数据时只能存入泛型指定的数据类型,如果存入其他数据类型,则会编译错误,避数据存入时的问题。
coll.add(new Integer(1)); //编译错误!
3、从集合中取出元素时,无需转型了。
如:String str1 = it.next();
优点
1、简化集合的使用
2、增强代码的可读性和稳定性

ArrayList<?> – ?:代表所有类型

ArrayList<? extends B> – ?:代表B类型或B的子类类型

ArrayList<? super B> – ?:代表B类型或B的父类类型

注意:泛型只存活在编码阶段,编译后泛型就不在了

package com.dream.generic;

public class Test01 {
	
	public static void main(String[] args) {
		/**
		 * 泛型的使用
		 */
		
		MyArrayList<Integer> list = new MyArrayList<>();
		list.add(123);
		
	}
}

package com.dream.generic;

import java.util.ArrayList;

public class Test02 {

	public static void main(String[] args) {
		/**
		 * 泛型限定
		 */

	}

	//?:代表所有类型
	public static ArrayList<?> method01(){

		ArrayList<String> list = new ArrayList<>();
		return list;
	}

	//ArrayList<? extends B> - ?:代表B类型或B的子类类型
	public static ArrayList<? extends B> method02(){
		//ArrayList<B> list = new ArrayList<>();
		ArrayList<C> list = new ArrayList<>();
		return list;
	}

	//ArrayList<? super B> - ?:代表B类型或B的父类类型
	public static ArrayList<? super B> method03(){
		//ArrayList<B> list = new ArrayList<>();
		ArrayList<A> list = new ArrayList<>();
		return list;
	}
}


七、比较器

Comparable - compareTo() - 内置比较器

Comparator - compare() - 外置比较器

注意 - 比较规则的返回值:

​ 返回值:负数-比比较对象小

​ 返回值:正数-比比较对象大

​ 返回值:0-和比较对象一致(不存储)

Student类

package com.dream.treeset_class;

public class Student implements Comparable<Student>{
	
	private String name;
	private int age;
	private char sex;
	private String classId;
	private String id;
	
	public Student() {
	}

	public Student(String name, char sex,int age, String classId, String id) {
		this.name = name;
		this.age = age;
		this.sex = sex;
		this.classId = classId;
		this.id = id;
	}

	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 char getSex() {
		return sex;
	}

	public void setSex(char sex) {
		this.sex = sex;
	}

	public String getClassId() {
		return classId;
	}

	public void setClassId(String classId) {
		this.classId = classId;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + ", sex=" + sex + ", classId=" + classId + ", id=" + id + "]";
	}
	
	@Override
	public boolean equals(Object obj) {
		if(this == obj){
			return true;
		}
		if(obj instanceof Student){
			Student stu = (Student) obj;
			if(this.classId.equals(stu.classId) && this.id.equals(stu.id)){
				return true;
			}
		}
		return false;
	}

	//排序方法
	//排序规则:年龄排序
	//返回值:负数-比比较对象小 
	//返回值:正数-比比较对象大 
	//返回值:0-和比较对象一致(不存储)
	@Override
	public int compareTo(Student o) {
		return this.age - o.age;
	}

}

测试类

package com.dream.treeset_class;

import java.util.Comparator;
import java.util.TreeSet;

public class Test04 {
	
	public static void main(String[] args) {
		/**
		 * 做实验 学习外置比较器(比较接口)
		 */
	
		//外置比较器
		//比较规则:先判断两个学生是否相同,再按照姓名长度,再按照年龄
		TreeSet<Student> set = new TreeSet<>(new Comparator<Student>() {
			@Override
			public int compare(Student o1, Student o2) {
				if(o1.equals(o2)){
					return 0;
				}
				if(o1.getName().length() != o2.getName().length()){
					return o1.getName().length() - o2.getName().length();
				}
				if(o1.getAge() != o2.getAge()){
					return o1.getAge() - o2.getAge();
				}
				return 1;
			}
		});
		
		set.add(new Student("麻生希", '女', 28, "2101", "001"));
		set.add(new Student("椎名空", '女', 23, "2101", "002"));
		set.add(new Student("北岛玲", '女', 27, "2101", "003")	);
		set.add(new Student("水野朝阳", '女', 31, "2101", "004"));
		set.add(new Student("三上悠亚", '女', 26, "2101", "005"));
		set.add(new Student("濑亚美莉", '女', 32, "2101", "006"));
		set.add(new Student("爱田奈奈", '女', 36, "2102", "001"));
		set.add(new Student("深田咏美", '女', 28, "2102", "002"));
		set.add(new Student("小西满里惠", '女', 28, "2102", "003"));
		set.add(new Student("桃谷绘里香", '女', 29, "2102", "004"));
		set.add(new Student("明日花绮罗", '女', 29, "2102", "005"));
		set.add(new Student("铃原爱蜜莉", '女', 29, "2102", "006"));
		set.add(new Student("波多野结衣", '女', 34, "2102", "007"));
		
		for (Student stu : set) {
			System.out.println(stu);
		}
	}           

}

注意事项

  1. Collection 和 Map的区别

Collection 存储单个值,可以直接操作迭代器

Map存储两个值(Key/Value),不可以直接操作迭代器

  1. 理解有序和无序

有序:存入顺序和取出顺序一致

无序:存入顺序和取出顺序不一致,无序不代表随机

  1. Iterator vs ListIterator

Iterator :遍历集合、删除元素

ListIterator:只能List接口下的实现类调用,遍历集合、删除元素、添加元素、替换元素、指定下标开始遍历元素、倒叙遍历

  1. ArrayList vs Vector
ArrayListVector
JDK1.2JDK1.0
线程不安全线程安全
Iterator、foreachIterator、foreach、Enumeration
  1. 集合的使用场景

ArrayList:存储数据

LinkedList:栈模式、队列模式

Vector:不用

Stack:不用

HashSet:去重复+无序

LinkedHashSet:去重复+有序

TreeSet:自然排序

HashMap:存储键值对+无序

Hashtable:存储键值对+无序

ConcurrentHashMap:存储键值对+无序

LinkedHashMap:存储键值对+有序

  1. HashMap vs Hashtable vs ConcurrentHashMap

    ​ HashMap 允许存储null键,线程不安全
    ​ Hashtable 不允许存储null键,线程安全(效率低)
    ​ ConcurrentHashMap 不允许存储null键,线程安全(效率高)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Helloword先生

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

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

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

打赏作者

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

抵扣说明:

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

余额充值