14 Java集合(集合框架+泛型+ArrayList类+LinkedList类+Vector类+HashSet类等)

本文介绍了Java集合框架的基础知识,包括集合的概念、数据结构、Collection接口及其常用方法,如ArrayList、LinkedList和Vector的实现原理和使用,以及HashSet的去重机制。此外,还涉及了迭代器的使用和泛型的基本应用。
摘要由CSDN通过智能技术生成

本篇主要是集合框架基础和List集合,Map集合等等后续更

14.1 集合框架

  • 什么是集合框架?

Java中的集合框架其实就是对**【数据结构】**的封装,这个封装中提供了一些常用方法,可方便操作数据,无需程序猿自定定义操作,只需要调用封装方法就可以完成对存在集合中数据【增删改查】
集合其实就是对数据结构一种封装,所以之前sun公司就把集合放置到一个统一包中进行管理【java.util】包

  • 什么是数据结构?

数据结构其实就是计算机,组织和存储数据形式
数据结构是指相互之间存在一种或多种特定关系的数据集合
通常情况下,精心选择数据结构可以带来更加高效运行和存储效率, 数据结构往往高效的原因在于**【检索算法】和【索引计数】**
常见数据结构:【数组、栈、链表(单向和双向)、哈希表、队列(单向和双向)、堆、树、图】
Java的集合框架其实就是对【数据结构实现】,我们需要掌握就是如何操作这个数据结构(即操作集合中方法),高效存储与处理数据
PS:根据不同数据结构,操作数据性能是不同(有地查询块、有的插入快、有地允许重复、有的不允许重复等等),在开发中只要选择合理数据结构即集合对数据存储与操作即可

  • Java中常见的集合框架

    习惯性说Java中集合有三大框架【List、Set和Map】

    如果详细说明的话应该2个框架3个实现

    • 2个框架: Collection 和 Map
    • 3个实现 :Collection这个集合下两个主要实现 List 和 set 所以称为三大集合List、set 和Map
  • 集合和数组最大区别在于:

    1. 集合中只能储存引用类型即对象
    2. 集合是一个变长容量,根据集合储存元素个数动态进行删减【扩容和减容】
    3. 数组是一个定长容器,创建大小数固定,无论存储多少数据长度都是唯一

常见三大集合框架:

  1. List【列表】:集合中存储对象是按照索引位置进行存储,允许存储重复数据
  2. Set【集】: 集合中存储对象不是按照特定方式进行存储,不允许出现重复数据
  3. Map【映射】:集合中每一个存储元素都是以一种【键值对key- value】方式进行存储的,以一种key和value的形式存储的,key 这个对象是不允许重复【唯一性】,value是允许重复
14.1.1 概念
  • 集合是一种对象容器,用于存放对象
  • 数组的缺点:
    • 1、数组定长,一旦定义不能改变
    • 2、数组中没有方法
    • 3、数组中只能存放相同的数据类型的数据
  • 集合特点:
    • 1、长度可以改变
    • 2、集合中丰富的操作元素的方法
    • 3、集合中只能存储引用数据类型的数据
  • 集合的分类
    • 1、单列集合 (集合中一个元素保存一个数据) Collection
    • 2、双列集合 (集合中一个元素保存两个数据) Map
14.1.2 集合架构
集合架构
请添加图片描述

14.2 Collection接口

单列集合的顶层接口

14.2.1 常用方法
  • add方法向集合集合中添加元素
  • clear方法,清空集合中所有元素
  • contains方法 判断集合是否包含某个元素
  • isEmpty判断集合是否为空
  • remove方法 移除集合中元素,返回boolean类型。如果集合中不包含次元素,则删除失败
  • size()返回集合中元素的个数
  • toArray将集合转换成数组。
  • addAll 向一个集合中添加另一个集合
  • containsAll 判断一个集合中是否包含另一个集合
  • removeAll 从一个集合中移除另一个集合
public class CollectionDemo {
	public static void main(String[] args) {
		//创建Collection对象
		Collection coll = new ArrayList();
		
		//Collection接口下常用的方法
		
		//add   向集合中添加元素
		coll.add("jack");
		coll.add(10);
		coll.add("rose");
		
		System.out.println(coll);
		
		//contains 判断集合中是否包含指定元素
		System.out.println(coll.contains("赵四"));
		
		//isEmpty  判断集合的元素个数是否为0     
		System.out.println(coll.isEmpty());
		
		//remove   移除集合中指定的元素,如果存在返回true、否则返回false
		coll.remove("jack1");
		System.out.println(coll);
		
		//size    获取集合中元素个数
		System.out.println(coll.size());
		
		//toArray 将集合变成数组 
		Object[] arr = coll.toArray();
		
		//Arrays.toString  将数组变成字符串形式
		System.out.println(Arrays.toString(arr));
		
		int[] nums = {1,2,3,4};
		//将数组转成集合
		List asList = Arrays.asList(nums);
		System.out.println(asList);
		
		
		Collection coll1 = new ArrayList();
		coll1.add("lilei");
		coll1.add("hanmeimei");
		//addAll   将另一个集合中元素添加到当前集合中
		coll1.addAll(coll);
		System.out.println(coll1);
 		//containsAll  判断集合中是否包含另一个集合
		System.out.println(coll1.containsAll(coll));
//		coll1.removeAll(coll);
//		System.out.println(coll1);
		
		//retainAll  保留coll中包含的元素
		coll1.retainAll(coll);
		System.out.println(coll1);
	}
}

14.3 迭代器

14.3.1 迭代器原理

迭代是重复反馈过程的活动,其目的通常是为了逼近所需目标或结果。每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值。

迭代器原理
请添加图片描述
//迭代器的作用:获取集合中的所有的元素		
Collection coll = new ArrayList();
coll.add("jack");
coll.add("rose");
coll.add(10);
coll.add(20.2);
//1、获取迭代器对象
Iterator it = coll.iterator();
while(it.hasNext()) {
    System.out.println(it.next());
}
System.out.println(coll);
14.3.2 迭代器使用常见问题
  • 1、迭代器迭代完成之后,迭代器的位置在最后一位。 所以迭代器只能迭代一次
  • 2、迭代器在迭代的时候,不要调用多次next方法,可能会出错 NoSuchElementException
  • 3、在迭代器迭代的时候,不能向集合中添加或者删除元素 ConcurrentModificationException
public class IteratorDemo {
	public static void main(String[] args) {
		//使用迭代器需要注意的问题
		
		//1、迭代器只能使用一次
//		Collection coll = new ArrayList();
//		coll.add("jack");
//		coll.add("rose");
//		coll.add(10);
//		coll.add(20.2);
//		Iterator it = coll.iterator();
//		while(it.hasNext()){
//			System.out.println(it.next());
//		}
//		while(it.hasNext()){
//			System.out.println(it.next());
//		}
		
		//2、迭代器使用的时候不能多次使用next方法
//		Collection coll = new ArrayList();
//		coll.add("jack");
//		coll.add("rose");
//		coll.add(10);
//		coll.add(20.2);
//		coll.add(100);
//		Iterator it = coll.iterator();
//		while(it.hasNext()) {
//			Object obj = it.next();
//			System.out.println(it.next());
//		}
		//3、迭代器在迭代的时候不要添加或者删除元素
		Collection coll = new ArrayList();
		coll.add("jack");
		coll.add("rose");
		coll.add(10);
		coll.add(20.2);
		coll.add(100);
		Iterator it = coll.iterator();
		while(it.hasNext()) {
			coll.remove(10);
			//coll.add("zhaosi");
			System.out.println(it.next());
		}
	}
}

14.4 泛型基本使用

泛型:参数化类型 JDK1.5之后

  • 用途:
    • 因为如果不使用泛型,那么向集合中添加元素,实际当做Object对象传递进去的,此时发生向上转型了当从集合中获取数据,得到的是Object类型,那么在使用的需要向下转型,才能正常使用。因此频繁向上向下转型。可能会出现类转换异常。 这个时候就需要使用泛型。
    • 泛型的作用实际上就是讲类型转换的检查提前到了编译期
  • 泛型擦除: JDK1.7之后
    • 集合类型<泛型> 变量名 = new 集合类型<>();
  • 泛型需要注意的问题:
    • 1、泛型上不存在多态
      • Collection coll = new ArrayList();//错误
    • 2、泛型只能是引用数据类型
      • 如果是基本数据类型,则使用它的包装类
public class GenericDemo {
	public static void main(String[] args) {
//		Collection coll = new ArrayList();
//		coll.add(new Student("我要去输液了",38));
//		coll.add(new Student("要输什么液",20));
//		coll.add(new Teacher("想你的夜",30));
//		coll.add("哈哈哈~~平衡了");
//		//获取迭代器对象
//		Iterator it = coll.iterator();
//		while(it.hasNext()) {
//			Student stu = (Student) it.next();
//			stu.play();
//		}
		
//		Collection<Student> coll = new ArrayList<>();
//		coll.add(new Student("我要去输液了",38));
//		//coll.add("");   不能添加其他类型的元素
//		coll.add(new Student("我要去输液了",38));
//		//获取迭代器对象
//		Iterator<Student> it = coll.iterator();
//		while(it.hasNext()) {
//			Student stu = it.next();
//			stu.play();
//		}
		
//		Collection<Person> coll = new ArrayList<Person>();
//		coll.add(new Student("我要去输液了",38));
		
//		Collection<Integer> coll = new ArrayList<Integer>();
	}
}
class Person{
}
class Teacher extends Person{
	String name;
	int age;
	public Teacher() {
	}	
	public Teacher(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}	
}
class Student extends Person{
	String name;
	int age;
	public Student() {
	}	
	public Student(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}	
	public void play() {
		System.out.println("就是玩儿");
	}
}

14.5 ArrayList类

14.5.1 常用方法
  • add(int index, E element)
  • remove(int index)
  • set(int index, E element)
  • get(int index)
  • subList(int beginIndex,int endIndex)
  • list.listIterator();
package com.qf.demo02;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class ArrayListDemo {
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		//List集合相对于Collection集合多了一些关于下标操作的方法
		
		//List集合的常用方法
		list.add("jack");
		list.add("rose");
		list.add("cxk");
		list.add("尼古拉斯");
		System.out.println(list);
		System.out.println("======================================");
		//在集合指定下标位置上添加元素      add(index, element)
		list.add(0, "李雷");
		list.add(3, "韩梅梅");
		list.add(6, "亚洲舞王");
		//list.add(10, "赵四");  下标范围:0~size
		System.out.println(list);
		System.out.println("======================================");
		//清空集合中所有的元素  clear()
		//list.clear();
		//System.out.println(list);
		System.out.println("======================================");
		
		//返回元素在集合中的下标,如果不存在返回-1
		System.out.println(list.indexOf("cxk"));
		//返回元素在集合中的下标(找到集合中最后一个相同元素),如果不存在返回-1
		System.out.println(list.lastIndexOf("cxk"));
		
		System.out.println("======================================");
		//移除集合中指定下标位置上的元素    下标范围:0 ~ size-1
		list.remove(0);
		System.out.println(list);
		
		System.out.println("======================================");
		//修改集合中指定下标位置上的元素     下标范围:0 ~ size-1
		list.set(1, "李雷");
		System.out.println(list);
		
		System.out.println("======================================");
		//截取集合中指定下标开始到结束位置上的元素
		List<String> list1 = list.subList(2, 5);
		System.out.println("list1----》"+list1);
		
		System.out.println("======================================");
		//获取指定下标位置上的元素
		System.out.println(list.get(0));
		
		/**
		 * List集合遍历的三种方式:
		 * 	 1、迭代器
		 *   2、for循环
		 *   3、foreach循环(增强for循环)  可以遍历数组和集合
		 *   
		 *   语法:
		 *   	for(元素的类型    变量  : 数组|集合){ //变量就表示遍历出来的元素
		 *   
		 *      }
		 */
		System.out.println("===================迭代器遍历===================");
		Iterator<String> it = list.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
		System.out.println("===================for循环遍历===================");
		for (int i = 0; i < list.size() ; i++) {
			System.out.println(list.get(i));
		}
		System.out.println("===================foreach循环遍历===================");
		for(String s : list) {
			System.out.println(s);
		}
		
		System.out.println("=================list集合的迭代器=====================");
		ListIterator<String> li = list.listIterator();
//		while(li.hasNext()) {
//			System.out.println(li.next());
//		}
//		
//		while(li.hasPrevious()) {
//			System.out.println(li.previous());
//		}
        
		while(li.hasNext()) {
			li.add("hehe");
			System.out.println(li.next());
		}
		System.out.println("--------------");
		while(li.hasPrevious()) {
			System.out.println(li.previous());
		}
	}
}
14.5.2 实现原理

ArrayList其底层实现使用数组

实现原理
请添加图片描述

14.6 LinkedList类

14.6.1 常用方法

常用的方法与ArrayList一致。自己独有一些向首尾添加移除等方法(可以模拟对列、堆栈等数据结构)

package com.qf.demo02;

import java.util.LinkedList;

public class LinkedListDemo {
	public static void main(String[] args) {
		//创建LinkedList对象
		LinkedList<String> list = new LinkedList<String>();
		list.add("jack");
		list.add("rose");
		list.add("cxk");
		list.add("李雷");
		list.add("韩梅梅");
		list.add(1, "马冬梅");
		System.out.println(list);
		
		list.addFirst("尼古拉斯");
		list.addLast("亚洲舞王");
		System.out.println(list);
		
		System.out.println("================================================");
		System.out.println(list.getFirst());
		System.out.println(list.getLast());
		System.out.println(list.get(3));
		
		
		System.out.println("================模拟栈结构==================");
		LinkedList<String> list1 = new LinkedList<String>();
		list1.push("aa");
		list1.push("bb");
		System.out.println(list1.pop());
		System.out.println(list1.pop());
		
		System.out.println("================模拟对列结构==================");
		LinkedList<String> list2 = new LinkedList<String>();
		//向对列的尾部添加元素
		list2.offer("哈哈");
		list2.offer("呵呵");
		list2.offer("嘻嘻");
		list2.offer("hiahia");
		//获取并移除对列的头部的元素
		System.out.println(list2.poll());
		System.out.println(list2.poll());
		System.out.println(list2.poll());
		System.out.println(list2.poll());
		//获取但不移除对列的头部的元素
		//System.out.println(list2.element());
		//获取但不移除对列的头部的元素
		//System.out.println(list2.peek());
		System.out.println(list2);
		
		//LinkedList集合三种遍历方式
	}
}
14.6.2 LinkedList实现原理
实现原理
请添加图片描述
14.6.3 堆栈和队列结构
堆栈和队列结构
请添加图片描述

14.7 Vector类

14.7.1 常用方法

ArrayList的方法基本一致

public class VectorDemo {
	public static void main(String[] args) {
		Vector<String> vector = new Vector<String>();
		vector.add("aa");
		System.out.println(vector);
		/**
		 * ArrayList、LinkedList、Vector的区别
		 * 
		 * ArrayList和Vector底层使用数组实现(增删慢、查询快)
		 *   ArrayList是当添加元素的时候,才会扩容数组,默认长度为10
		 *   Vector是当创建对象的是,就创建长度为10的数组
		 *   ArrayList线程不安全,效率高
		 *   Vector是线程安全的,效率低
		 *   
		 * LinkedList底层使用双向链表实现(增删快、查询慢)
		 */
	} 
}
14.7.2 实现原理

ArrayList的底层一致,使用数组实现

14.7.3 常见面试问题

ArrayListLinkedListVector的区别:

  • ArrayList和Vector底层使用数组实现(增删慢、查询快)
    • ArrayList是当添加元素的时候,才会扩容数组,默认长度为10, Vector是当创建对象的是,就创建长度为10的数组
    • ArrayList线程不安全,效率高 Vector是线程安全的,效率低
  • LinkedList底层使用双向链表实现(增删快、查询慢)

14.8 HashSet类

14.8.1 HashSet基本使用

常用方法与Collection接口中定义的方法一致

特点:

  • 无序 (插入顺序)
  • 无下标
  • 不可重复
HashSet<String> set = new HashSet<String>();
set.add("jack");
set.add("rose");
set.add("cxk");
set.add("jack");
System.out.println(set);
14.8.2 HashSet 去重原理

HashSet底层去重:

​ 首先会比较两个对象的hashCode的值,如果hashCode值不一样,则直接认为两个对象是不同的对象,如果HashCode值一样,那么就会比较两个方法的equals方法, 如果equals方法返回false,则表示两个对象是不同的对象,如果equals方法返回true,则表示两个对象是相同的对象,则不会向HashSet中添加

总之:HashSet确定对象是否重复,是先判断hashcode再判断equals,两者都相等则认为是相同对象

HashSet<User> userSet = new HashSet<User>();
User cxk = new User("cxk", "123");
userSet.add(cxk);
userSet.add(new User("jack", "456"));
userSet.add(new User("王校长", "输液..."));
userSet.add(new User("jack", "456")); // 相同对象无法插入
userSet.add(cxk);// 相同对象无法插入

重写hashCodeequals方法

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((password == null) ? 0 : password.hashCode());
    result = prime * result + ((username == null) ? 0 : username.hashCode());
    return result;
}
@Override
public boolean equals(Object obj) {
    //判断两个对象是否是同一个对象
    if (this == obj)
        return true;
    //判断比较的对象是否为null
    if (obj == null)
        return false;
    //getClass() 返回对象的真实(运行)类型
    if (getClass() != obj.getClass())
        return false;
    User other = (User) obj;
    if (password == null) {
        if (other.password != null)
            return false;
    } else if (!password.equals(other.password))
        return false;
    if (username == null) {
        if (other.username != null)
            return false;
    } else if (!username.equals(other.username))
        return false;
    return true;
}

14.9 LinkedHashSet类

LinkedHashSet

特点::

  • 1、有序
  • 2、无下标
  • 3、不可重复

与父类的方法一致,去重的原理,也与父类一致

public class LinkedHashSetDemo {
	public static void main(String[] args) {
		//LinkedHashSet  有序(链表维护顺序)  不能重复
		LinkedHashSet<String> set = new LinkedHashSet<>();
		set.add("jack");
		set.add("大娃");
		set.add("二娃");
		set.add("rose");
		set.add("爷爷");
		set.add("爷爷");
		for (String s : set) {
			System.out.println(s);
		}
        //1、底层实现 (LinkedHashMap)
        //2、去重原理 (与hashSet一致)
	}
}

14.10 Collections工具类

集合: 工具类(Collections)

  • Collections.reverse(List<?> list)
    • 将集合中的元素反转
  • Collections.shuffle(List<?> list)
    • 将集合中的元素随机打乱
  • Collections.sort(List<?> list)
    • 将集合中的元素排序 (必须要实现Comparable接口)
public class CollectionsDemo {
	public static void main(String[] args) {
		List<String> list = new ArrayList<String>();
		list.add("jack");
		list.add("大娃");
		list.add("二娃");
		list.add("rose");
		list.add("妖怪");
		list.add("蛇妖");
		list.add("蛇妖");
		System.out.println(list);
		//按照字典顺序
		Collections.sort(list);
		System.out.println(list);
		
		//将集合元素进行翻转
		Collections.reverse(list);
		System.out.println(list);
		
		//将集合中的元素进行随机打乱
		Collections.shuffle(list);
		System.out.println(list);
		
		//Arrays数组工具类      Collections集合工具类
	}
}
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

yinying293

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

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

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

打赏作者

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

抵扣说明:

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

余额充值