集合框架和泛型二

news2024/11/19 21:15:25

一、Set接口

1. Set接口概述

java.util.Set 不包含重复元素的集合、不能保证存储的顺序、只允许有一个 null

public interface Set<E>
extends Collection<E>

抽象方法,都是继承自 java.util.Collection 接口。
Set 集合的实现类有很多,在此我们重点了解 HashSetTreeSetLinkedHashSet
不允许使用索引:Set集合中没有提供使用索引来访问元素的方法,因为元素没有固定的顺序。
非同步:不是线程安全的。
HashSet:基于哈希表实现,具有O(1)的平均时间复杂度的查找、插入和删除操作。
TreeSet:基于红黑树实现,具有排序功能,元素会按照自然排序或指定的比较器顺序进行排序。
LinkedHashSet:基于哈希表和链表实现,保留元素的插入顺序,具有O(1)的平均时间复杂度的查找、插入和删除操作。

2.HashSet

public class HashSet<E>
extends AbstractSet<E>
implements Set<E>, Cloneable, Serializable

实现了 Set 接口,底层实现是 HashMap 。不保证迭代顺序,允许 null 元素。

  • 非线程安全的
  • 如果 add 的值已存在( equals 方法返回 true ,基本数据类型自动装箱)返回 false
  • 如果 HashSet 中存的是对象,需要重写此对象类中的 equals 和 hashCode() 方法
    HashSet集合的特点:
    (1)元素唯一性:不允许重复的元素。每个元素只能存在一次。
    (2)无序性
    (3)基于哈希表
    (4)非同步
    (5)只能存在一个null元素
HashSet()构造一个新的空集合; 底层实现HashMap实例具有默认初始容量(16)和负载因子(0.75)。
HashSet(Collection<?extends E> c)构造一个包含指定集合中的元素的新集合
HashSet(int initialCapacity)构造一个新的空集合,默认初始容量(initialCapacity)和负载因子(0.75)
HashSet(int initialCapacity, float loadFactor)构造一个新的空集合; 底层HashMap实例具有指定的初始容量和指定的负载因子

3.TreeSet

public class TreeSet<E>
extends AbstractSet<E>
implements NavigableSet<E>, Cloneable, Serializable
  • 非线程安全
  • 值必须可比较(元素实现 Comparable 接口、传递 比较器 Comparator 对象)
  • 不能存 null
  • 判断是否是重复元素,是按照自然比较/比较器进行比较

就是说a.compareTo(b) == 0,如果是 true ,那么 add(a) 之后的 add(b) 将会返回 false ,也就是添加失败。

ceiling(E e)E返回此集合中大于或等于给定元素的最小元素,如果没有这样的元素,则返回null。
floor(E e)E返回此集合中小于或等于给定元素的最大元素,如果没有这样的元素,则返回null。
headSet(E toElement)SortedSet<[E]>返回此集合中元素严格小于toElement的部分的视图。
tailSet(E fromElement)SortedSet<[E]>返回此集合中元素严格大于或等于fromElement的部分的视图。
higher(e)E返回此集合中严格大于给定元素的最小元素,如果没有这样的元素,则返回null
higher(e)lower(e)返回此集合中严格小于给定元素的最大元素,如果没有这样的元素,则返回null。
TreeSet<String> set = new TreeSet(List.of("null", "a", "a", "b", "c", "e", "f",
"g"));
System.out.println(set); // [a, b, c, e, f, g, null]
// 返回此集合中大于或等于给定元素的最小元素,如果没有这样的元素,则返回null。
String ceiling = set.ceiling("d");
System.out.println(ceiling);// e
// 返回当前在此集合中的第一个(最低的)元素。
String first = set.first();
System.out.println(first); // a
// 返回此集合中小于或等于给定元素的最大元素,如果没有这样的元素,则返回null。
String floor = set.floor("d");
System.out.println(floor); // c
// 返回此集合中元素严格小于toElement的部分的视图。
SortedSet<String> headSet = set.headSet("c");
System.out.println(headSet); // a, b
// 返回此集合中严格大于给定元素的最小元素,如果没有这样的元素,则返回null。
String higher = set.higher("c");
System.out.println(higher); // e
// 返回此集合中元素严格大于或等于fromElement的部分的视图。
SortedSet<String> tailSet = set.tailSet("c");
System.out.println(tailSet); // c, e, f, g, null
// 迭代
for (Object obj : set){
System.out.println(obj);
}

4.LinkedHashSet

public class LinkedHashSet<E>
extends HashSet<E>
implements Set<E>, Cloneable, java.io.Serializable
  • 哈希表和双向链表实现的 Set 接口
  • 具有可预测的迭代次序(有序)
  • 内部实现是 LinkedHashMap ,顺序是插入顺序

二、Iterator接口

1.Iterator接口概述

Iterator接口表示对集合进行迭代的迭代器。Iterator接口为集合而生,专门实现集合的遍历。主要有两个方法:

  • hasNext():判断是否存在下一个可以访问的元素,有返回true。
  • next():返回要访问的下一个元素。
    由Collection接口派生的类或接口,都实现了iterator()方法,iterator()方法返回一个Iterator对象。

2.使用Iterator遍历集合

package collection;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * 创建一个Map,完成以下操作:
 *  将我国省份和其简称存到 Map 集合中
 *  将省份名称中包含"江"的省份从集合中删除
 *  遍历输出集合元素
 */
public class Basic {
    public static void main(String[] args) {
        Map<String,String> map=new HashMap();
        map.put("北京", "京");
        map.put("上海", "沪");
        map.put("天津", "津");
        map.put("重庆", "渝");
        map.put("河北", "冀");
        map.put("山西", "晋");
        map.put("辽宁", "辽");
        map.put("吉林", "吉");
        map.put("黑龙江", "黑");
        map.put("江苏", "苏");
        map.put("浙江", "浙");
        map.put("安徽", "皖");
        map.put("福建", "闽");
        map.put("江西", "赣");
        map.put("山东", "鲁");
        map.put("河南", "豫");
        map.put("湖北", "鄂");
        map.put("湖南", "湘");
        map.put("广东", "粤");
        map.put("海南", "琼");
        map.put("四川", "川");
        map.put("贵州", "黔");
        map.put("云南", "滇");
        map.put("陕西", "陕");
        map.put("甘肃", "甘");
        map.put("青海", "青");
        map.put("台湾", "台");
        map.put("内蒙古", "蒙");
        map.put("广西", "桂");
        map.put("西藏", "藏");
        map.put("宁夏", "宁");
        map.put("新疆", "新");
        map.put("香港", "港");
        map.put("澳门", "澳");
        System.out.println(map.size());

        //将省份名称中包含"江"的省份从集合中删除
        Set<Map.Entry<String, String>> entries = map.entrySet();
        Iterator<Map.Entry<String, String>> iterator = entries.iterator();
        while (iterator.hasNext()){
            Map.Entry<String, String> next = iterator.next();
            if (next.getKey().contains("江")){
                iterator.remove();
            }
        }

        //遍历
        for (String key:map.keySet()) {
            System.out.println(key);
        }
        System.out.println(map.size());
    }
}

三、Map接口

Map 接口不是 Collection 的子接口,使用键、值映射表来存储。

public interface Map<K,V>
  • Map 不能有重复的键(覆盖),每个键可以映射到最多一个值
  • 允许将映射内容视为一组键、值集合或键值映射集合
  • key 不要求有序,不可以重复。 value 也不要求有序,但可以重复
  • 当使用对象作为 key 时,要重写 equals 和 hashCode 方法
`JDK9` 提供了创建不可修改 Map 对象的方法:
1. Map.of
2. Map.ofEntries
3. Map.copyOf

Map 的实现类较多,在此我们关注 HashMapTreeMapHashTableLinkedHashMap

1.TreeMap

public class TreeMap<K,V>
extends AbstractMap<K,V>
implements NavigableMap<K,V>, Cloneable, Serializable
  • 继承 AbstractMap ,一个红黑树基于 NavigableMap 实现
  • 非线程安全的
  • key 不能存 null ,但是 value 可以存 null
  • key 必须是可比较的 (实现Comparable 接口,传递一个 Comparator 比较器)
    在这里插入图片描述

2.HashTable

public class Hashtable<K,V>
extends Dictionary<K,V>
implements Map<K,V>, Cloneable, Serializable
  • 该类实现了一个哈希表,它将键映射到值
  • 不允许 null 作为键和值
  • 默认初始容量( initialCapacity )为 11 ,默认负载因子( loadFactor )为 0.75f
  • 同步的(线程安全的)
  • 不保证顺序
  • 扩容方式是旧容量的2倍 +1
    - 为什么hashtable的扩容方式选择为2n+1
    - 为了均匀分布,降低冲突率
  • 数组 + 链表方式存储实现Hash表存储
  • 添加值时
    - 如果 hash 一样 equals 为 false 则将当前值添加到链表头
    - 如果 hash 一样 equals 为 true 则使用当前值替换原来的值 ( key 相同
    在这里插入图片描述
public synchronized V put(K key, V value) {
// 值不能为 null
if (value == null) {
throw new NullPointerException();
}
// 确认 key 不在 hashtable 中存在
Entry<?,?> tab[] = table;
// 计算 key 的 hash
int hash = key.hashCode();
// 找 key 应在存放在 数组中的位置
int index = (hash & 0x7FFFFFFF) % tab.length;
// index 位置的元素的 key 和 当前的 key 不一样
@SuppressWarnings("unchecked")
Entry<K,V> entry = (Entry<K,V>)tab[index];
for(; entry != null ; entry = entry.next) {
// 判断 key 是否相同
if ((entry.hash == hash) && entry.key.equals(key)) {
// 当 key 一样时,替换值
V old = entry.value;
entry.value = value;
return old;
}
}
// 当 key 在 hashtable 中不存在时,添加
addEntry(hash, key, value, index);
return null;
}
private void addEntry(int hash, K key, V value, int index) {
Entry<?,?> tab[] = table;
// 判断是否需要 "扩容"
if (count >= threshold) {
// 对数组进行扩容 (2n + 1),将原有元素重新计算 hash
rehash();
tab = table;
// 将当前的 key 也重新计算 hash
hash = key.hashCode();
index = (hash & 0x7FFFFFFF) % tab.length;
}
// 原来数组中的 entry 对象
@SuppressWarnings("unchecked")
Entry<K,V> e = (Entry<K,V>) tab[index];
// 创建一个 新的 entry 对象, 放到 数组中
tab[index] = new Entry<>(hash, key, value, e);
// 元素个数 +1
count++;
// 修改次数 +1
modCount++;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1000996.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

分布式AKF拆分原则

目录 1 前言2 什么是AKF3 如何基于 AKF X 轴扩展系统&#xff1f;4 如何基于 AKF Y 轴扩展系统&#xff1f;5 如何基于 AKF Z 轴扩展系统&#xff1f;6 小结 1 前言 当我们需要分布式系统提供更强的性能时&#xff0c;该怎样扩展系统呢&#xff1f;什么时候该加机器&#xff1…

网络安全(黑客)技术自学

前言 一、什么是网络安全 网络安全可以基于攻击和防御视角来分类&#xff0c;我们经常听到的 “红队”、“渗透测试” 等就是研究攻击技术&#xff0c;而“蓝队”、“安全运营”、“安全运维”则研究防御技术。 无论网络、Web、移动、桌面、云等哪个领域&#xff0c;都有攻与防…

高忆管理:突破22万亿!五大保险巨头总资产创历史新高

阅历了几年深度转型的稳妥业正在冲破迷雾。 券商我国记者统计显现&#xff0c;本年上半年&#xff0c;我国人寿、我国人保、我国安全、我国太保、新华稳妥等五大A股上市险企总财物破22万亿元&#xff0c;半年度营收1.5万亿元。从3至5年中长周期来看&#xff0c;稳妥集团公司体…

【大数据】Kafka 入门指南

Kafka 入门指南 1.Kafka 简介2.Kafka 架构3.分区与副本4.偏移量5.消费者组6.总结 1.Kafka 简介 Apache Kafka 是一种高吞吐、分布式的流处理平台&#xff0c;由 LinkedIn 开发并于 2011 年开源。它具有 高伸缩性、高可靠性 和 低延迟 等特点&#xff0c;因此在大型数据处理场景…

“JSR303和拦截器在Java Web开发中的应用与实践“

目录 引言JSR303什么是JSR303?为什么要使用JSR303?常用注解快速入门JSR303 拦截器什么是拦截器拦截器与过滤器应用场景快速入门拦截器 总结 引言 在Java Web开发过程中&#xff0c;我们经常会遇到需要对输入数据进行验证和处理&#xff0c;同时需要对请求进行拦截与控制的需…

纷享销客受邀出席CDIE2023数字化创新博览会 助力大中型企业增长

2023年&#xff0c;穿越周期&#xff0c;用数字化的力量重塑企业经营与增长的逻辑&#xff0c;再次成为企业数字化技术应用思考的主旋律&#xff0c;以数字经济为主线&#xff0c;数字技术融入产业发展与企业增长为依据&#xff0c;推动中国企业数字化升级。 9月5日&#xff0c…

Git多人开发解决冲突案例

准备工作&#xff1a; 1.创建一个gitee远程仓库https://gitee.com/xxxxxxx.git 2.初始化两个本地git仓库用户&#xff0c;目的是模拟多人协作开发时提交代码发生冲突的场景 3.解决冲突并提交。 进入正题&#xff1a; lisi 通过vim指令修改readme.md文件内容&#xff0c;推送到…

合宙Air724UG LuatOS-Air LVGL API控件-表格(Table)

表格&#xff08;Table&#xff09; 示例代码 --创建表格Table1 lvgl.table_create(lvgl.scr_act(),nil)--设置表格为4行5列lvgl.table_set_row_cnt(Table1,4)lvgl.table_set_col_cnt(Table1,5)--给每个单元格赋值lvgl.table_set_cell_value(Table1, 0, 0, "选手")l…

QT生成ICO文件

生成ICO文件 #include <QApplication> #include <QImage> #include <QIcon> #include <QFile> #include <QDebug> #include <QPixmap>int main(int argc, char* argv[]) {QApplication app(argc, argv);// 读取图片文件QImage image(&quo…

Python类的概念

类 类的技术名词解释 ● 类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。 ● 类变量&#xff1a;类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用…

功率放大器的定义详解

功率放大器是一种电子放大器&#xff0c;主要用于将输入信号的功率放大到足以驱动负载或输出器件所需的水平。通常&#xff0c;功率放大器会将低电平高电流的输入信号转换成高电平低电流的输出信号&#xff0c;以便给负载提供足够的功率。 功率放大器广泛应用于各种应用场合&am…

(Note)中文EI检索期刊目录

ei和sci、ssci一样是国际知名的期刊数据库&#xff0c;ei不仅收录国际知名的刊物&#xff0c;也收录了一些国内期刊&#xff0c;为方便投稿选刊&#xff0c;Elsevier官网更新了的EI Compendex期刊目录&#xff0c;那么 国内ei期刊有哪些? 经查询共有250余种期刊&#xff0c;新…

【LeetCode-面试经典150题-day23】

目录 108. 将有序数组转换为二叉搜索树 148.排序链表 427.建立四叉树 23.合并K个升序链表 108. 将有序数组转换为二叉搜索树 题意&#xff1a; 给你一个整数数组 nums &#xff0c;其中元素已经按 升序 排列&#xff0c;请你将其转换为一棵 高度平衡 二叉搜索树。 高度平衡 二…

如何实现自己在家搭建全端口P2P穿透?快解析内网穿透

对于有公网主机&#xff0c;有一定的操作能力&#xff0c;需要独立资源配置使用的&#xff0c;可以选择自行搭建内网映射服务。那么如何实现自己搭建全端口P2P穿透呢&#xff1f;下面为大家提供了不同场景下的不同方法&#xff0c;供大家使用时参考。 SSH是一种安全的远程登录…

一个方法用js生成随机双色球、大乐透

代码如下&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><s…

【C++】构造函数分类 ① ( 构造函数分类简介 | 无参构造函数 | 有参构造函数 | 拷贝构造函数 | 代码示例 - 三种类型构造函数定义与调用 )

文章目录 一、构造函数分类1、构造函数分类简介2、构造函数分类代码分析无参构造函数有参构造函数拷贝构造函数 二、代码示例 - 三种类型构造函数定义与调用 一、构造函数分类 1、构造函数分类简介 C 构造函数可以分为以下几类 : 无参构造函数 : 最简单也是默认的构造函数 , 函…

gitlab在项目中创建自己的分支的顺序操作,一整套流程

gitlab在项目中创建自己的分支的顺序操作&#xff0c;一整套流程 目录概述需求&#xff1a; 设计思路实现思路分析 参考资料和推荐阅读 Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better…

【C++】day4学习成果:仿写string类等等

1.仿照string类&#xff0c;完成myString 类 代码&#xff1a; #include <iostream> #include <cstring>using namespace std;class myString {private:char *str; //记录c风格的字符串int size; //记录字符串的实际长度public://无参构造myS…

C++学习之list的实现

在了解学习list实现之前我们首先了解一下关于迭代器的分类&#xff1a; 按功能分类&#xff1a; 正向迭代器 反向迭代器 const正向迭代器 const反向迭代器 按性质分类&#xff1a; 单向迭代器 只能 例如单链表 双向迭代器 可&#xff0c;也可-- 例如双…

酒店固定资产管理怎么分类

在酒店业中&#xff0c;固定资产的管理是至关重要的一环。它不仅影响到企业的运营效率和盈利能力&#xff0c;而且直接影响到客户体验和品牌形象。因此&#xff0c;对于酒店管理者来说&#xff0c;合理、有效地进行固定资产管理是一项必不可少的任务。本文将探讨酒店固定资产的…