20.Java集合(一)

Java集合(一)


一、集合概述与Collection (掌握)

1.1 数组的特点和弊端

 * 一、Java的内存层面,对多个对象进行统一的管理和操作的容器有什么呢? 数组、集合
 * 
 * 二、1. 数组在存储数据方面的特点:
 * 		> 数组一旦初始化以后,其长度就是确定的。
 * 		> 数组有索引,可以方便的对指定位置上的元素进行查找、替换
 * 		> 数组存储的数据:有序的、使用连续的内存空间
 * 		> 数组在定义时,就明确了存储的数据的类型。
 * 			比如:String[] arr,Object[]
 *    2. 数组在存储数据方面的弊端:
 * 		> 数组一旦初始化以后,其长度就不可改变--->如果需要扩容,必须新建数组
 * 		> 数组在插入、删除等操作时,效率很差
 * 		> 可以表达的多个对象的关系较为简单,不能描述更为丰富的对象关系
 * 		> 数组中可以使用的方法非常少

1.2 集合框架结构

 * 	|-----Collection:存储一个一个的数据
 * 		|-----List:存储有序的、可以重复的数据 : 替换数组,"动态数组"
 * 			|-----ArrayList/LinkedList/Vector
 * 		|-----Set:存储无序的、不可重复的数据: 高中的集合
 * 			|-----HashSet/LinkedHashSet/TreeSet
 * 	|-----Map:存储一对一对的数据(key-value):高中的函数。 y = f(x) (x1,y1),(x2,y2)
 * 		|-----HashMap/LinkedHashMap/TreeMap/Hashtable/Properties

在这里插入图片描述

在这里插入图片描述

1.3 本章要求

 * 本章对大家的要求:
 * 	层次一:针对不同特点的数据,能够选择对应接口的主要的类进行实例化和方法的调用
 *  层次二:熟悉接口的不同的实现类的区别、特点
 *  层次三:相关接口实现类的底层实现:存储结构

1.4 Collection中的常用方法

@Test
	public void test1(){
		
		Collection c1 = new ArrayList();
		//1. add(Object obj):添加元素obj到当前集合中
		c1.add(123);//自动装箱
		c1.add("AA");
		c1.add(new Date(234234324L));
		c1.add("BB");
		System.out.println(c1);
		
		//2.size():获取集合中元素的个数
		System.out.println(c1.size());
		
		//3.addAll(Collection coll):将coll集合中的元素添加到当前集合中。
		Collection c2 = new ArrayList();
		c2.add(345);
		c2.add("CC");
		c1.addAll(c2);
//		c1.add(c2);
		System.out.println(c1.size());
		
		//5.clear():清空当前集合
		c1.clear();
		
		//4.isEmpty():判断当前集合是否为空。
		System.out.println(c1.isEmpty());
		System.out.println(c1);
	}
	@Test
	public void test2(){
		Collection c1 = new ArrayList();
		c1.add(123);//自动装箱
		c1.add(new Person("Tom",12));
		c1.add(new String("AA"));
		c1.add(new Date(234234324L));
		c1.add("BB");
		
		//6.contains(Object obj):判断当前集合中是否包含obj元素
		//具体的:需要调用obj对象所在类的equals(Object o)
		System.out.println(c1.contains(new String("AA")));
		System.out.println(c1.contains(new Person("Tom",12)));
		
		//7.containsAll(Collection coll):判断当前集合中是否包含coll集合中的所有元素
		Collection c2 = new ArrayList();
		c2.add(1234);
		c2.add(new String("BB"));
		System.out.println(c1.containsAll(c2));
	}
	
	@Test
	public void test3(){
		Collection c1 = new ArrayList();
		c1.add(123);//自动装箱
		c1.add(new Person("Tom",12));
		c1.add(new String("AA"));
		c1.add(123);//自动装箱
		c1.add(new Date(234234324L));
		c1.add("BB");
		
		//8.remove(Object obj):删除当前集合中首次出现的obj元素
		System.out.println(c1.remove(1234));
		System.out.println(c1);
		
		//9.removeAll(Collection coll):差集:从当前集合中移除其与coll集合共有的元素
		Collection c2 = new ArrayList();
		c2.add(1234);
		c2.add(new String("BB"));
		c1.removeAll(c2);
		System.out.println(c1);
		
	}
	@Test
	public void test4(){
		Collection c1 = new ArrayList();
		c1.add(123);//自动装箱
		c1.add(new Person("Tom",12));
		c1.add(new String("AA"));
		c1.add(new Date(234234324L));
		c1.add("BB");
		
		//10.retainAll(Collection coll):交集:获取当期集合与coll集合共有的元素
		Collection c2 = new ArrayList();
		c2.add(123);//自动装箱
		c2.add(new Person("Tom",12));
		c2.add(new String("AA"));
		c2.add("BB");
		c2.add(new Date(234234324L));
//		c1.retainAll(c2);
//		System.out.println(c1);
		
		//11. equals(Object obj):判断当前集合与obj元素是否相等
		//要想返回true,要求形参obj也是一个同类型的集合对象,同时集合元素都相同。(如果是List的话,要求顺序也相同)
		System.out.println(c1.equals(c2));
		
		//12.hashCode():返回当前集合对象的哈希值
		System.out.println(c1.hashCode());
	}

1.5 数组与集合的转换

    @Test
	public void test5(){
		Collection c1 = new ArrayList();
		c1.add(123);//自动装箱
		c1.add(new Person("Tom",12));
		c1.add(new String("AA"));
		c1.add(new Date(234234324L));
		c1.add("BB");
		
		//13.toArray():将集合转换为数组
		Object[] arr = c1.toArray();
		for(int i = 0;i < arr.length;i++){
			System.out.println(arr[i]);
		}
		
		//如何将数组转换为集合?yes!
        //使用Arrays的asList(T...t)
		String[] arr1 = {"AA","CC","MM","GG"};
		List list = Arrays.asList(arr1);
		System.out.println(list);
		
		List list1 = Arrays.asList("AA","CC","MM");
		
		//笔试题:
		Integer[] arr2 = new Integer[]{1,2,3};
		int[] arr3 = new int[]{1,2,3};
		List list2 = Arrays.asList(arr2);
		List list3 = Arrays.asList(arr3);
		List list4 = Arrays.asList(1,2,3);
		System.out.println(list2.size());//3
		System.out.println(list3.size());//1
		System.out.println(list4.size());//3
		System.out.println(list3);//[[I@4459eb14]
		
	}

1.6 集合的遍历:使用Iterator接口

@Test
	public void test1(){
		Collection c1 = new ArrayList();
		c1.add(123);//自动装箱
		c1.add(new Person("Tom",12));
		c1.add(new String("AA"));
		c1.add(new Date(234234324L));
		c1.add("BB");
		
//		System.out.println(c1);
		//Iterator对象称为迭代器(设计模式的一种),主要用于遍历 Collection 集合中的元素。
		Iterator iterator = c1.iterator();
		//方式一:
//		System.out.println(iterator.next());
//		System.out.println(iterator.next());
//		System.out.println(iterator.next());
//		System.out.println(iterator.next());
//		System.out.println(iterator.next());
//		//报NoSuchElementException
//		System.out.println(iterator.next());
		
		//方式二:不推荐
//		for(int i = 0;i < c1.size();i++){
//			System.out.println(iterator.next());
//		}
		//方式三:推荐
		//hasNext():判断集合的下个位置是否还有元素
		while(iterator.hasNext()){
			//next():① 指针下移 ② 将下移以后位置上的元素返回
			Object obj = iterator.next();
			System.out.println(obj);
		}
		
	}

对应的迭代器的执行原理:

在这里插入图片描述

错误的写法:

//错误的遍历方式
	@Test
	public void test2(){
		Collection c1 = new ArrayList();
		c1.add(123);//自动装箱
		c1.add(new Person("Tom",12));
		c1.add(new String("AA"));
		c1.add(new Date(234234324L));
		c1.add("BB");
		//错误方式一:
//		Iterator iterator = c1.iterator();
//		while(iterator.next() != null){
//			System.out.println(iterator.next());
//			
//		}
		//错误方式二:每次调用iterator()时,都会返回一个迭代器对象,指针从头开始
//		while(c1.iterator().hasNext()){
//			Object obj = c1.iterator().next();
//			System.out.println(obj);
//		}
	}

1.7 增强for循环

  • 用来遍历集合
@Test
	public void test1(){
		Collection c1 = new ArrayList();
		c1.add(123);//自动装箱
		c1.add(new Person("Tom",12));
		c1.add(new String("AA"));
		c1.add(new Date(234234324L));
		c1.add("BB");
		
		//格式:for(集合元素类型  变量名 : 待遍历的集合对象的引用)
		for(Object obj : c1){
			
			System.out.println(obj);
		}
		
	}
  • 用来遍历数组
@Test
	public void test2(){
		int[] arr = {1,2,3,4,5};
		
		for(int i : arr){
			System.out.println(i);
		}
	}
  • 面试题
//面试题
	@Test
	public void test3(){
		int[] arr = {1,2,3,4,5};
		//操作一:
//		for(int i : arr){
//			i = 6;
//			System.out.println(i);
//		}
		//操作二:
		for(int i = 0;i < arr.length;i++){
			arr[i] = 6;
		}
		
		for(int i = 0;i < arr.length;i++){
			System.out.println(arr[i]);
		}
	}

二、List接口

2.1 List中的常用方法

//List是Collection的子接口,Collection中声明的方法,在List的实现类中都可以使用。
	//此外,由于List是有序的,所有额外添加了一些方法。
	/*
	 * void add(int index, Object ele):在index位置插入ele元素
	 * boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来
	 * Object get(int index):获取指定index位置的元素
	 * int indexOf(Object obj):返回obj在集合中首次出现的位置
	 * int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
	 * Object remove(int index):移除指定index位置的元素,并返回此元素
	 * Object set(int index, Object ele):设置指定index位置的元素为ele
	 * List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex位置的子集合
	 * 
	 * 
	 * 	总结:(必须掌握)
	 * 		增:add(Object obj)
	 * 		删:remove(Object obj)/remove(int index)
	 * 		改:set(int index, Object ele)
	 * 		查:get(int index)
	 * 		插:add(int index, Object ele)
	 * 		长度:size()
	 * 		遍历:iterator() / 增强for
	 */
	@Test
	public void test1(){
		List list = new ArrayList();
		list.add(123);//自动装箱
		list.add(567);
		list.add("AA");
		
//		list.remove("AA");
//		list.remove(new Integer(123));
//		list.set(1, "BB");
		list.add(1, "CC");
		
		System.out.println(list);
//		System.out.println(list.get(2));
		System.out.println(list.size());
	}
	
	@Test
	public void test2(){
		List list = new ArrayList();
		list.add(123);//自动装箱
		list.add(567);
		list.add("AA");
		//方式一:使用迭代器
//		Iterator iterator = list.iterator();
//		while(iterator.hasNext()){
//			System.out.println(iterator.next());
//		}
		//方式二:增强for
//		for(Object obj : list){
//			System.out.println(obj);
//		}
		
		//方式三:一般for循环
		for(int i = 0;i < list.size();i++){
			System.out.println(list.get(i));
		}
	}
	
	@Test
	public void test3(){
		List list = new ArrayList();
		list.add(123);//自动装箱
		list.add(567);
		list.add("AA");
		
		List list1 = Arrays.asList(1,2,3);
		list.addAll(1, list1);
		System.out.println(list);
		
		List list2 = list.subList(1,3);
		System.out.println(list2);
	}

2.2 不同的实现类

|-----Collection:存储一个一个的数据
	|-----List:存储有序的、可以重复的数据 : 替换数组,"动态数组"
		|-----ArrayList:List的主要实现类;线程不安全的,效率高;底层使用Object[]存储
		|-----LinkedList:底层使用双向链表存储数据;对于频繁的插入、删除操作,使用此类效率高。
		|-----Vector:List的古老实现类;线程安全的,效率低;底层使用Object[]存储
				
面试题:区分ArrayList、LinkedList、Vector
		
		
数据结构中的数据存储结构:
	> 真实结构:① 顺序表(一维数组)
			 ② 链表
	> 抽象数据结构(ADT):栈、队列、树、图

	@Test
	public void test3(){
		List list = new ArrayList();
		list.add(123);//自动装箱
		list.add(567);
		list.add("AA");
		
		List list1 = Arrays.asList(1,2,3);
		list.addAll(1, list1);
		System.out.println(list);
		
		List list2 = list.subList(1,3);
		System.out.println(list2);
	}

三、练习题

练习1:

•	键盘录入学生信息,保存到集合中。
o	循环录入的方式,1:表示继续录入,0:表示结束录入。
o	定义学生类,属性为姓名,年龄,使用学生对象保存录入数据。
o	使用ArrayList集合,保存学生对象,录入结束后,用foreach遍历集合。
•	代码实现,效果如图所示:

在这里插入图片描述

public class StudentTest {
    public static void main(String[] args) {

        Scanner scanner = new Scanner(System.in);
        ArrayList stuList = new ArrayList();

        for (;;) {

            System.out.println("选择(录入 1 ;结束 0)");
            int x = scanner.nextInt();//根据x的值,判断是否需要继续循环

            if (x == 1) {
                System.out.println("姓名");
                String name = scanner.next();
                System.out.println("年龄");
                int age = scanner.nextInt();
                Student stu = new Student(age, name);
                stuList.add(stu);

            } else if (x == 0) {
                break;

            } else {

                System.out.println("输入有误,请重新输入");
            }
        }

        for (Object stu : stuList) {
            System.out.println(stu);
        }
    }
}

练习2:

•	随机生成30个数,范围2-100,获取其中的质数。
•	代码实现,效果如图所示:

在这里插入图片描述

写法一:

public class PrimeNumberPrintTest1 {

    public static void main(String[] args) {

        ArrayList numberList = new ArrayList();
        int num = 0;
        for (int i = 0; i < 30; i++) {
            num = (int)(Math.random() * (100-2+1) ) + 2;
            if(!numberList.contains(num)){
            	 numberList.add(num);
            }else{
            	i--;
            }
        }

        System.out.println(numberList);
        
        
        
        ArrayList primeList = new ArrayList();//用于存储所有的质数
		
        int j;
        boolean flag;
        for (int i = 0; i < numberList.size(); i++) {
            
            flag = false;
            int number = (int) numberList.get(i);
            for (j = 2; j <= Math.sqrt(number); j++) {
                if (number % j == 0){
                    flag = true;
                    break;
                }
            }
            if (!flag){
            	primeList.add(number);
            }
        }
        
        System.out.println("当前随机数中的质数有:");
        for(Object obj : primeList){
        	System.out.println(obj);
        }
    }

}

写法二:

public class PrimeNumberPrintTest2 {

	public static void main(String[] args) {

		List numberList = generateRandomNumber(30, 2, 100);

		System.out.println(numberList);

		
		List primeList = getPrimeNumber(numberList);

		System.out.println("当前随机数中的质数有:");
		System.out.println(primeList);
	}

	/**
	 * 获取30个随机数,范围为2-100
	 * 
	 * @Description
	 * @author shkstart
	 * @date 2020年3月16日上午9:34:37
	 * @param size
	 * @param startNumber
	 * @param endNumber
	 * @return
	 */
	private static List generateRandomNumber(int size, int startNumber, int endNumber) {
		ArrayList numberList = new ArrayList();
		for (int i = 0; i < size; i++) {
			int num = (int) (Math.random() * (endNumber - startNumber + 1)) + startNumber;
			if (!numberList.contains(num)) {
				numberList.add(num);
			} else {
				i--;
			}
		}

		return numberList;

	}
	/**
	 *  获取指定List中所有数值中的质数
	 * @Description 
	 * @author shkstart
	 * @date 2020年3月16日上午9:37:08
	 * @param numberList
	 * @return
	 */
	private static List getPrimeNumber(List numberList) {
		ArrayList primeList = new ArrayList();// 用于存储所有的质数

		for (int i = 0; i < numberList.size(); i++) {

			boolean flag = false;
			int number = (int) numberList.get(i);
			for (int j = 2; j <= Math.sqrt(number); j++) {
				if (number % j == 0) {
					flag = true;
					break;
				}
			}
			if (!flag) {
				primeList.add(number);
			}
		}
		return primeList;
	}
}

四、小结

  • 字符串相关的类:String\StringBuffer\StringBuilder (重点)

  • 比较器:Comparable \ Comparator (可以实现java中的对象比较大小、排序) (重点)

  • 日期时间的API

    • jdk 8之前的API:java.util.Date (子类:java.sql.Date) 、Calendar、SimpleSDateFormat(格式化、解析)
    • jdk8中API:Instant、LocalDate\LocalTime\ LocalDateTimeDateTimeFormater
  • 其他的常用类:BigInteger、BigDecimal

  • Collection\List\Set\Map存储数据的特点

  • Collection中的常用方法(掌握)

    • 遍历时,使用迭代器(Iterator)
  • List

    • List中的常用方法: 增、删、改、查、插、长度、遍历
    • 三个实现类的对比—>面试题
    • ArrayList、LinkedList的源码分析
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值