博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java进阶6——集合
阅读量:2351 次
发布时间:2019-05-10

本文共 5987 字,大约阅读时间需要 19 分钟。

集合&迭代器

集合体系结构

  • 集合体系图
    这里写图片描述
  • 集合的体系是如何形成的
    由于不同的数据结构(数据的组织,存储方式),所以java为我们提供了不同的集合,但不同的数据结构中又有许多类似的功能,所以将这些类似的功能向上提取,最终形成集合的体系

Collection中的常用功能

boolean add(Object e); // 向集合中添加元素void clear(); // 清空集合中所有元素boolean contains(Object o); // 判断集合中是否包含某个元素boolean isEmpty(); // 判断集合中的元素是否为空boolean remove(Object o); // 根据元素的内容来删除某个元素int size(); // 获取集合的长度Object[] toArray(); // 能够将集合转换成数组并把集合中的元素存储到数组中

迭代器

java中提供了很多个集合,它们在存储元素时,采用的存储方式不同。我们要取出这些集合中的元素,可通过一种通用的获取方式来完成。

Collection集合元素的通用获取方式:在取元素之前先要判断集合中有没有元素,如果有,就把这个元素取出来,继续在判断,如果还有就再取出出来。一直把集合中的所有元素全部取出。这种取出方式专业术语称为迭代。
集合中把这种取元素的方式描述在Iterator接口中。

  • Iterator接口的常用方法如下
Iterator 集合对象.iterator(); // 返回一个Iterator的对象hasNext(); // 判断集合中是否有元素可以迭代next(); // 用来返回迭代的下一个元素,并把指针向后移动一位
  • 使用迭代器的注意事项:
    使用迭代器会碰到一个异常Exception in thread "main" java.util.ConcurrentModificationException:并发修改异常
    这是因为在使用迭代器时,我们直接通过集合进行添加,而迭代器的原理其实就是一个集合的副本,当集合中的元素与迭代器中的元素个数或值不同时,就会发生并发修改异常,解决办法有两种,第一种不使用迭代器进行遍历,第二种使用迭代器的子类对象,如果要修改集合,直接通过迭代器去修改副本中的数据,修改之后,副本会同步集合中的数据

增强for&泛型

泛型

  • 泛型的引入
    由于集合可以存储任意类型的对象,当我们存储了不同类型的对象,就有可能在转换的时候出现类型转换异常,所以java为了解决这个问题,给我们提供了一种机制,叫做泛型
  • 泛型的使用
    当类上定义<>的时候就可以使用泛型,例如ArrayList类的定义:
    class ArrayList,那么我们在创建ArrayList对象的时候就可以指定<>中E的类型
    ArrayList al=new ArrayList(),那么String就把E替换掉了这里的E可以替换为T或?,都表示泛型

增强for

增强for循环是JDK1.5以后出来的一个高级for循环,专门用来遍历数组和集合的。它的内部原理其实是个Iterator迭代器,所以在遍历的过程中,不能对集合中的元素进行增删操作

  • 格式:
for(元素的数据类型  变量 : Collection集合or数组的对象){}

常见数据结构

数组

  • 采用该结构的集合,对元素的存取有如下的特点:
    查找元素快:通过索引,可以快速访问指定位置的元素
    增删元素慢 ,每次添加元素需要移动大量元素或这创建新的数组
    这里写图片描述

链表

  • 采用该结构的集合,对元素的存取有如下的特点:
    A:多个节点之间,通过地址进行连接。例如,多个人手拉手,每个人使用自己的右手拉住下个人的左手,依次类推,这样多个人就连在一起了。
    B:查找元素慢:想查找某个元素,需要通过连接的节点,依次向后查找指定元素
    C:增删元素快:
    增加元素:只需要修改连接下个元素的地址即可。
    删除元素:只需要修改连接下个元素的地址即可
    这里写图片描述
  • 使用的选择
    由上述两个的特点可以得出一下结论:
    如果查询较多,则使用数组结构的集合
    如果增删较多,则使用链表结构的集合

栈&队列

  • 堆栈,采用该结构的集合,对元素的存取有如下的特点:
    先进后出(即,存进去的元素,要在后它后面的元素依次取出后,才能取出该元素)。例如,子弹压进弹夹,先压进去的子弹在下面,后压进去的子弹在上面,当开枪时,先弹出上面的子弹,然后才能弹出下面的子弹。
  • 队列,采用该结构的集合,对元素的存取有如下的特点:
    先进先出(即,存进去的元素,要在后它前面的元素依次取出后,才能取出该元素)。例如,安检。排成一列,每个人依次检查,只有前面的人全部检查完毕后,才能排到当前的人进行检查。
    这里写图片描述

List体系

List体系特点

A:有序的(存储和读取的顺序是一致的)

B:有整数索引
C:允许重复的

List的特有功能

void add(int index, E element); // 将元素添加到index索引位置上E get(int index); // 根据index索引获取元素E remove(int index); // 根据index索引删除元素E set(int index, E element); // 将index索引位置的的元素设置为element

LinkedList特有功能

LinkedList底层使用的是链表结构,因此增删快,查询相对ArrayList较慢

void addFirst(E e); // 向链表的头部添加元素void addLast(E e); // 向链表的尾部添加元素E getFirst(); // 获取链头的元素,不删除元素E getLast(); // 获取链尾的元素,不删除元素E removeFirst(); // 返回链头的元素并删除链头的元素E removeLast(); // 返回链尾的元素并删除链尾的元素

Set体系

Set体系的特点(与List体系的三个特点都相反)

A:存入集合的顺序和取出集合的顺序不一致

B:没有索引
C:存入集合的元素没有重复

HashSet集合

  • HashSet唯一性原理
规则:新添加到HashSet集合的元素都会与集合中已有的元素一一比较    首先比较哈希值(每个元素都会调用hashCode()产生一个哈希值)        如果新添加的元素与集合中已有的元素的哈希值都不同,新添加的元素存入集合        如果新添加的元素与集合中已有的某个元素哈希值相同,此时还需要调用equals(Object obj)比较            如果equals(Object obj)方法返回true,说明新添加的元素与集合中已有的某个元素的属性值相同,那么新添加的元素不存入集合             如果equals(Object obj)方法返回false, 说明新添加的元素与集合中已有的元素的属性值都不同, 那么新添加的元素存入集合

下面这个例子很重要

public class Demo {    public static void main(String[] args) {        HashSet
hashSet = new HashSet
(); Person p1 = new Person(12,"zhangsan"); Person p2 = new Person(12,"san"); Person p3 = new Person(13,"san"); hashSet.add(p1); System.out.println(""); hashSet.add(p2); System.out.println(""); hashSet.add(p3); System.out.println(""); for (Person person : hashSet) { System.out.println(person); } }}package com.bsw.hashsetDemo;public class Person { int age; String name; public Person(int age, String name) { super(); this.age = age; this.name = name; } @Override public String toString() { return "Person [age=" + age + ", name=" + name + "]"; } @Override public int hashCode() { return 1; } @Override public boolean equals(Object obj) { Person person = (Person)(obj); System.out.println(this.name + "---------------" + person.name); if (!name.equals(person.name)) { return false; } if (age != person.age) { return false; } return true; }}

这张图是上述案例输出的结果

上述案例的输出结果
这个结果是因为源码中下图的方法进行判断,如果比较两个值得key不相同的话,就不会执行equals方法,如果key相同,则会执行双与后的equals方法
这里写图片描述

  • hashCode方法优化:
    如果让hashCode()方法返回一个固定值,那么每个新添加的元素都要调用equals(Object obj)方法比较,那么效率较低
    只需要让不同属性的值的元素产生不同的哈希值,那么就可以不再调用equals方法比较提高效率

Collections中的方法

static void swap(List list, int i, int j); // 将指定列表中的两个索引进行位置互换// 例子:Collections.swap(集合对象, 索引1, 索引2);static void  sort(List
list); // 按照列表中元素的自然顺序进行排序// 例子:Collections.sort(集合对象);static void shuffle(List list); // 是否,随机置换// 例子:Collections.shuffle(集合对象);static void reverse(List list); // 反转// 例子:Collections.reverse(集合对象);static void fill(List list, Object obj); // 使用指定的对象填充指定列表的所有元素// 例子:Collections.fill(集合对象, 指定的填充元素);static void copy(List dest, List src); // 是把源列表中的数据覆盖到目标列表// 例子:Collections.copy(目标集合对象, 源集合对象);这里需要注意,目标集合长度大于等于源集合对象static int binarySearch(List list, Object key); // 使用二分查找法查找指定元素在指定列表的索引位置 // 例子:Collections.binarySearch(集合对象, 指定索引);

面试题:Collection和Collections有什么区别?

Collection是集合体系的最顶层,包含了集合体系的共性
Collections是一个工具类,方法都是用于操作Collection

Map接口概述

Map集合与Collection集合的区别

  • Collection集合中的所有元素都是孤立的,可以理解为单身状态
  • Map集合中的所有元素是以键值对存储的,一个键对应一个值,键不可重复,但是值可以重复,可以理解为夫妻状态
  • 因此,通常将Collection的集合称为单列集合,Map的集合称为多列集合

Map常用功能

A:映射功能(添加):    V put(K key, V value); // 以键=值的方式存入Map集合,如果key存在,则覆盖value,并将原来的value返回B:获取功能:    V get(Object key); // 根据键获取值    int size(); // 返回Map中键值对的个数C:判断功能:    boolean containsKey(Object key); // 判断Map集合中是否包含键为key的键值对    boolean containsValue(Object value); // 判断Map集合中是否包含值为value键值对    boolean isEmpty(); // 判断Map集合中是否没有任何键值对 D:删除功能:    void clear(); // 清空Map集合中所有的键值对    V remove(Object key); // 根据键值删除Map中键值对E:遍历功能:    Set
> entrySet(); // 将每个键值对封装到一个个Entry对象中,再把所有Entry的对象封装到Set集合中返回 Set
keySet(); // 将Map中所有的键装到Set集合中返回 Collection
values(); // 返回集合中所有的value的值的集合

Map的两种遍历方式

  • 通过keySet()方法,获取所有key值,遍历key得到对应的value
  • 通过entrySet()方法,获取一个装有多个Entry对象的Set集合,遍历集合,通过entry对象获取对应的key和value
你可能感兴趣的文章
快速识别图片类型
查看>>
理解云原生
查看>>
docker常见问题答疑
查看>>
mac最简配置maven
查看>>
虚拟机性能监控与故障处理工具
查看>>
GIT的一些操作
查看>>
ZooKeeper 四字命令
查看>>
Mysql InnoDB锁问题
查看>>
ZooKeeper编程 基础教程
查看>>
Java 集合框架
查看>>
kafka 操作
查看>>
Java 集合框架 算法
查看>>
Java 集合框架 Set实现
查看>>
Java 集合框架 List实现
查看>>
Java 集合框架 Map 实现
查看>>
kafka 简单入门
查看>>
maven常用命令汇总
查看>>
Redis 方案
查看>>
ZooKeeper 数据与存储配置
查看>>
ZooKeeper 安装部署
查看>>