2.8 Java之集合(Lish和Set篇)

集合概述

Java 集合也称容器,util包下,用于存储对象,分为 Collection 和 Map 两大体系

  • Collection接口:
  • Set接口:元素无序不可重复的集合 —类似高中的“集合”
  • List接口:元素有序可重复的集合 —”动态”数组
  • Map接口:具有映射关系“key-value对”的集合
    类似于函数 y = f(x) (x1,y1) (x2,y2),每个点就是键值对

Collection接口继承树

这里写图片描述

  • Collection:接口,定义存储数据的功能,无直接实现类,定义了两个子接口
  • Collections:工具类
  • 迭代器接口用于遍历集合元素
  • ArrayList类底层通过数组实现的
  • 主要6个实现类(SortedSet是接口)

Collection接口的方法

这里写图片描述

  • 第一行利用多态性,创建Collection接口的实现类对象
  • 123是包装类,add方法的参数为对象
  • add方法参数为对象,addAll方法参数为集合类对象
  • Arrays为数组的工具类
  • asList方法返回collection的子接口list(可将数组转化为集合)

这里写图片描述
这里写图片描述
这里写图片描述

  • ArrayList类重写了toString()方法,所以打印ArrayList,即打印其所有元素
  • 引申:
  • 集合里元素要求重写equals()方法(当元素的属性相同时,可认为是相同元素,而不是比较地址)
  • 若没重写,根据object类的equals方法,即比较地址值

这里写图片描述

  • containsAll方法即将集合元素每一个拿出来,进行contains比较,若出现一个则结果为false
  • retainAll方法对应取交集,改变了主动调用的集合

这里写图片描述
这里写图片描述

  • 哈希值决定存储位置,即栈空间通过该值指向堆空间区域
  • 黄色波浪线:未使用泛型
  • removeAll对应取差集,更改了主动调用的集合
  • toArray转化的数组类型为Object类型,因为collection存储的元素也是Object类型

这里写图片描述

  • 返回一个迭代器接口实现类的对象
  • 采用法三,因为现成的方法,上方有个多态性语句(别忘)

迭代总结

这里写图片描述

  • i看作指针,初始在第一个元素的上方
  • i.next():将指针向下移动并返回值

错误示范
这里写图片描述

问题:间隔打印+最后元素的后面为空

增强for循环

这里写图片描述
这里写图片描述

  • 冒号前:局部变量,集合中每个元素的类型
  • 每次取一个元素赋值给局部变量,不改变原始数据

##for循环和增强for循环
这里写图片描述
这里写图片描述
输出结果
这里写图片描述

原因:每次取一个元素赋值给局部变量,不改变原始数据


#List接口
总览:
这里写图片描述

  • Collection接口和Map接口并列
  • Properties子类用于处理属性文件

##ArrayList类
这里写图片描述

  • 该类视作动态数组
  • List有序,所以可在指定位置添加
  • 打印list,元素位置是有序的
  • add()方法是添加,不是覆盖对应位置元素,后方元素依次后退
  • indexOf判断元素出现的位置,要重写equals方法,原因同以往章节

这里写图片描述
这里写图片描述

  • 截取子list是左闭右开

这里写图片描述
这里写图片描述

  • 打印list,元素有序性

##LinkedList

  • 适合频繁的增加和删除操作
  • 不是数组结构,为链表结构

##Vector
古老,处理速度缓慢,弃用吧


#Set接口

##Collection接口回顾
这里写图片描述

##Set接口概述
这里写图片描述

  • 可添加null
  • 无序性!=随机性
  • 无序性指的是存储空间的无序性,存储位置根据哈希值,哈希算法要求可保证元素的唯一性,而List是开辟一整块连续区域
  • 哈希算法:不同元素的哈希值不同,类比坐位置,先hashcode找位置,没人直接坐,看有人占了座才调用equals方法比较
  • HashSet重写了ToString方法,打印引用即打印集合元素
  • 对于set:不可重复性要靠equals方法以及hashcode方法保证(缺一不可)
    意味着自定义的类加入Set,要重写上述两方法
  • 对于list:不可重复性只靠equals方法就行
  • hashcode方法要求属性值一样,则hash值一样,反之,亦如此
    hashcode与equals的一致性
  • hash值不同,直接存储,值相同,才调用equals方法比较
    ##实例
    这里写图片描述

能否加入Set集合,看hashcode方法,返回hash值不同,直接存储,值相同,才调用equals方法比较,属性又相同,才不存储

##hashcode方法重写
这里写图片描述

  • hashcode的写法采用提供的迭代写法,不采用注释里的写法,原因:
    避免类似30+10=29+11的错误,违反了唯一性

##LinkedHashSet
遍历顺序与添加顺序一致,因为链表维护添加顺序,并不能改变存储位置的无序性

原因如下
这里写图片描述

  • 三部分:前向索引,后向索引,值,即双向链表
    这里写图片描述

  • 遍历快,利用索引如水银泻地

  • 添加慢 要维护链表

TreeSet

这里写图片描述

  • 元素为String,包装类排序按从小到大(根据重写的Comparable接口内的方法)

自然排序

重写Comparable接口的方法
这里写图片描述

  • 上述方法若单单只比较一个属性,若两对象该属性一致,其他属性不一致,则后来的对象也不能添加到集合set中
  • 可利用String类型或包装类已重写的comparable接口内的方法
  • return 0很必要,不用抛异常的方法,return 0代表比较后元素的属性一致,即相同元素(实际可能未必),则不添加进set集合中
  • compareTo方法在Set中优先级高于hashcode和equals方法,换句话说set集合看 compareTo方法来判断是否添加入集合中

测试类
这里写图片描述

  • 要求Treeset添加的对象为同一类(编译时不报错,运行时才报错),因为要比较属性
  • 关注遍历使用(Object str : set),因为Set集合的元素默认是Object类型,而add方法的实参虽然是String,但形参是Object类型,没有使用泛型的锅
  • person能否添加,全看 compareTo方法

定制排序

这里写图片描述

  • 少写一个方法(Comparator接口还有equals方法),因为类对象的根父类Object已经重写了equals方法
  • compare方法和上述compareTo方法内容一致,且都要求三位一体(注释解释)

简写如下(匿名内部类)
这里写图片描述


这里写图片描述

  • compare方法比较的是customer,只能添加customer
  • 每次添加对象时,自动找引用变量com对应的接口实现类的 compareTo方法
compare和compareTo辨析
  • 一个写在添加的类里,一个在添加的类外
  • 若添加的类可修改,则在类内部实现comparable接口
  • 若添加的类无法修改,则在类外部利用Comparator接口指定排序
  • 若两者都书写,最后定制排序优先于自然排序

TreeSet练习

MyDate类
这里写图片描述

  • 书写属性注意顺序,影响自动生成的构造器

Employee类
这里写图片描述
这里写图片描述


自然排序

这里写图片描述

实现接口
这里写图片描述
这里写图片描述


Equals与Hashcode方法

  • MyDate类的两方法:
    这里写图片描述

  • Employee类的两方法:
    这里写图片描述

  • equals仍要书写,会与collection接口的部分方法对应,比如contains,还是要调用equals方法

  • 先向mydate加入hashcode方法,再向employee添加hashcode

一个注意点
这里写图片描述

  • 若employee类不重写compareTo方法,则一个对象都添加不了(JDK7.0后)

测试类
这里写图片描述
输出结果
这里写图片描述

  • 不是按字母顺序,内部由hashcode排序,6次添加最后只加入5个元素,因为名字一样了(compareTo方法只看名字属性)

###定制排序
这里写图片描述
这里写图片描述

  • 定制排序优先
  • 存入Set中的对象类型相同
  • int类型成员变量直接相减来判断大小
  • Set存储位置仍然是无序(hashcode决定存储位置)
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值