java --- 集合进阶

目录

一、单列集合顶层接口 Collection

1.1 基本方法

1.2 Collection 的遍历方式

二、list集合

1.2 ArrayList

 Vector 底层结构

1.3 LinkedList

ArrayList 和 LinkedList 比较

三、set接口

 3.1、Set 接口和常用方法

3.2 HashSet

HashSet 底层机制(HashMap)

 3.3  LinkedHashSet

3.4 TreeSet

四、双列集合Map

 4.1  Map 接口实现类的特点

4.2 Map 接口和常用方法

4.3 Map 接口的三种遍历方法

法一:先获取key的单列集合,再通过key获取vale

法二 获取每个键值对,再getKey ,getValue

法三:lambda表达式,利用Map的forEach方法

4.4  HashMap

4.5 LinkedHashMap

4.6 TreeMap


一、单列集合顶层接口 Collection

1.1 基本方法

常用方法:

Collection是一个接口,我们不能直接创建对象,需要通过他实现类的对象

1.2 Collection 的遍历方式

迭代器遍历

public class collection {public static void main(String[] args) {Collection<String> c1 = new ArrayList<>(10);c1.add("zhangsan");c1.add("lisi");c1.add("wangwu");c1.add("maliu");//迭代器的遍历Iterator<String> it = c1.iterator();while(it.hasNext()){String s = it.next();//返回当前元素,并向后移动System.out.println(s);}System.out.println(it.hashCode());System.out.println(it);}}

注意点

 Collection接口遍历元素:增强 for 循环

所有的单列集合还有数组都可以通过增强for循环遍历

这里和C++的用法是一样的

//使用增强forfor(String s : c1){System.out.println(s);}

使用lambda简化forEach遍历

二、list集合

List相比于Colection最大的改变就是加入了索引

2.1 List接口常用方法:

  1. void add (int index,Object ele) :在index位置插入ele元素;
  2. boolean addAll (int index,Collection eles) :从index位置开始将eles集合中的所有元素添加进来;
  3. Object get (int index) :获取指定index位置的元素;
  4. int indexOf (Object obj) :返回obj在集合中首次出现的位置;
  5. int lastIndexOf (Object obj) :返回obj在集合中末次出现的位置;
  6. Object remove (int index) :移除指定index位置的元素,并返回此元素;
  7. Object set (int index,Object ele) :设置指定index的位置的元素为ele,相当于是替换;
  8. List subList (int fromIndex,int toIndex) :返回从fromIndex到toIndex位置的子集合;
public static void main(String[] args) {//向上转型,用List来接收ArrayListList l1 = new ArrayList();//1. void add (int index,Object ele) :在index位置插入ele元素;l1.add(1);l1.add(2);l1.add(3);System.out.println(l1);//[1, 2, 3]//2. boolean addAll (int index,Collection eles) :从index位置开始将eles集合中的所有元素添加进来;List l2 = new ArrayList();l2.add(10);l2.add(20);l1.addAll(l2);System.out.println(l1);//[1, 2, 3, 10, 20]//3. Object get (int index) :获取指定index位置的元素;Object o1 = l1.get(0);Object o2 = l1.get(3);//4. int indexOf (Object obj) :返回obj在集合中首次出现的位置;int x1 = l1.indexOf(10);int x2 = l1.indexOf(1);
//5. int lastIndexOf (Object obj) :返回obj在集合中末次出现的位置;int x3 = l1.indexOf(20);int x4 = l1.indexOf(2);//6. Object remove (int index) :移除指定index位置的元素,并返回此元素;Object o3 = l1.remove(0);System.out.println(l1);//7. Object set (int index,Object ele) :设置指定index的位置的元素为ele,相当于是替换;l1.set(0,666);System.out.println(l1);//8. List subList  (int fromIndex,int toIndex) :返回从fromIndex到toIndex位置的子集合;List l3 = l1.subList(0,2);System.out.println(l3);}

1.2 ArrayList

  • ArrayList 是由数组来实现数据存储的;
  • ArrayList基本等同于 Vector ,除了 ArrayList是线程不安全的,但执行效率高,在多线程的情况下不建议用ArrayList

 Vector 底层结构

  • Vector 底层也是一个对象数组,protected Object[ ] elementData;
  • Vector 是线程同步的,即线程安全,Vector类的操作方法带有synchronized
  • 在开发中,需要线程同步安全时,考虑使用Vector

底层原理

扩容机制

1.3 LinkedList

  • LinkedList 实现了双向链表和双端队列的特点
  • 可以添加任意元素(元素可以重复),包括null;
  • 线程不安全,没有实现同步
  • LinkedList底层维护了一个双向链表;
  • LinkedList中维护了两个属性first和last分别指向 首节点 和 尾节点;
  • 每个节点(Node对象),里面又维护了prev、next、item三个属性,其中通过prev指向前一个,通过next指向后一个节点,最终完成双向链表;
  • 所以 LinkedList的元素的添加和删除不是通过数组完成的,相对来说效率较高;
import java.util.Iterator;
import java.util.LinkedList;public class LinkListCRUD {public static void main(String[] args) {LinkedList linkedList = new LinkedList();//增linkedList.add(1);//size=0添加一个新节点,首尾指针都指向这个新节点linkedList.add(2);//last指向新节点,first还是指向第一个节点,next指向新节点linkedList.add(3);System.out.println("增后: "+linkedList);//删linkedList.remove();//默认删除第一个System.out.println("删后: "+linkedList);//就是去掉指针//改linkedList.set(1,999);System.out.println("改后: "+linkedList);//查//get(1) 得到双向链表的第二个对象Object o = linkedList.get(1);System.out.println(o);//999//因为LinkedList是实现了List接口,所以遍历方式:Iterator iterator = linkedList.iterator();while (iterator.hasNext()) { //快捷输入ititObject next =  iterator.next();System.out.println(next);}//还有增强for 和普通for 遍历}
}

ArrayList 和 LinkedList 比较

集合底层结构增删的效率改查的效率
ArrayList可变数组较低,数组扩容较高
LinkedList双向链表较高,通过链表追加较低

如何选择 ArrayList 和 LinkedList :

  1. 如果改查的操作较多,选择 ArrayList;
  2. 如果增删的操作较多,选择 LinkedList;
  3. 一般程序中,80%-90%都是查询,因此大部分会使用ArrayList;
  4. 在项目中,灵活选择,可以一个模块用LinkedList,一个模块用ArrayList;

多线程的情况还是考虑 Vector ,因为它是线程安全的

三、set接口

Set 接口介绍:

  1. 无序(添加和取出的顺序不一致),没有索引;
  2. 不允许重复元素,所以最多包含一个null;
  3. JDK API 中Set的常用实现类有:HashSet 和 TreeSet;

 3.1、Set 接口和常用方法

Set 接口的常用方法

  • 和 List 接口一样,Set 接口也是 Collection 的子接口,所以常用方法和Collection接口一样

Set 接口的遍历方式

  • 同 Collection 的遍历一样:
    • 迭代器遍历
    • 增强 for
    • 但 不能用索引 的方式来获取; (因为Set无序
public class Set1 {public static void main(String[] args) {//Set是接口,不能直接实现,通过他的实现类Hashset来模拟//Set不能放重复元素//Set遍历的时候无序,和放入顺序不同,但是有固定的顺序Set s1 = new HashSet();s1.add("xx1");s1.add("xx2");s1.add("xx3");s1.add("xx4");System.out.println(s1);//迭代器遍历Iterator it = s1.iterator();while(it.hasNext()){Object o1 =it.next();System.out.println(o1);}System.out.println("hhhhhhh");//增强for遍历for(Object o : s1){System.out.println(o);}//不能索引遍历,且set接口对象没有get()方法}
}

3.2 HashSet

  1. HashSet实现了Set接口;
  2. HashSet实际上是HashMap,可以从源码看出;
  3. 可以存放 null 值,但是只能有一个null;
  4. HashSet 不保证元素是有序的,取决于hash后,再确定索引的结果;
  5. 不能有重复元素 / 对象;
import java.util.HashSet;public class HashSet1 {public static void main(String[] args) {HashSet hs = new HashSet();hs.add("zhangsan");hs.add("lisi");hs.add("wangwu");hs.add("maliu");System.out.println(hs);hs.remove("lisi");}
}
HashSet 底层机制(HashMap)

HashSet 底层其实是HashMap,HashMap底层是(数组+链表+红黑树)(链地址法

 3.3  LinkedHashSet

  1. LinkedHashSet 是 HashSet 的子类,继承HashSet,实现了Set接口;
  2. LinkedHashSet 底层是一个 LinkedHashMap,底层维护了一个 数组+双向链表;
  3. LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置,同时使用链表维护元素的次序,这使得元素看起来是以插入顺序保存的;
  4. LinkedHashSet 不允许添加重复元素;

3.4 TreeSet

TreeSet的独特之处在于它的构造器可以传入比较器,所以TreeSet常用来排序

TreeSet 底层是 TreeMap

public static void main(String[] args) {TreeSet t1 = new TreeSet();t1.add("aaa");t1.add("x");t1.add("bb");t1.add("hhhh");System.out.println(t1);//默认排序:首字母ASCII由小到大//[aaa, bb, hhhh, x]//如果我们想按字符串大小排序//使用TreeSet提供的一个构造器,传入一个比较器(匿名内部类)指定排序规则TreeSet t2 = new TreeSet(new Comparator() {@Overridepublic int compare(Object o1, Object o2) {return ((String)o1).length() - ((String)o2).length();}});t2.add("aaa");t2.add("x");t2.add("bb");t2.add("hhhh");System.out.println(t2);//按照字符串长度排序//[x, bb, aaa, hhhh]}

四、双列集合Map

Map为双列集合,Set集合的底层也是Map,只不过有一列是常量所占,只使用到了一列

 4.1  Map 接口实现类的特点

  1. Map 与 Collection 并列存在,用于保存具有映射关系的数据:Key - Value
  2. Map 中的 Key 和 Value 可以是任何引用类型的数据,会封装到 HashMap$Node对象中;
  3. Map中的 Key 不允许重复,原因和 HashSet 一样;
  4. Map 中的 Value 可以重复;
  5. Map 的 Key 可以为 null,value 也可以为 null,但 key 为 null 只能有一个;
  6. 常用 String 类作为 Map 的 key,当然,其他类型也可以,但不常用;
  7. Key 和 Value 之间存在单向一对一关系,即通过指定的 Key 总能找到对应的 Value;

4.2 Map 接口和常用方法

  • put :添加
  • remove : 根据键删除映射关系
  • get : 根据键获取值
  • size : 获取元素个数
  • isEmpty : 判断个数是否为0
  • clear : 清除
  • containsKey : 查找键是否存在
 public static void main(String[] args) {Map m1 = new HashMap();m1.put("zhangsan",100);m1.put("lisi",99);m1.put("wangwu",98);m1.put("maliu",97);System.out.println(m1);//{lisi=99, zhangsan=100, maliu=97, wangwu=98}System.out.println(m1.get("zhangsan"));System.out.println(m1.get("maliu"));System.out.println(m1.size());System.out.println(m1.isEmpty());System.out.println(m1.containsKey("wangwu"));m1.clear();System.out.println(m1);}

4.3 Map 接口的三种遍历方法

法一:先获取key的单列集合,再通过key获取vale

keySet()

public class Map遍历 {public static void main(String[] args) {Map<String,Integer> m1 = new HashMap();m1.put("zhangsan",100);m1.put("lisi",99);m1.put("wangwu",98);m1.put("maliu",97);//方法一:先获取键(先获取key的单列集合),再通过键获取值//1.增强forSet<String> keys = m1.keySet();for(String k : keys){System.out.println(k + " - "+m1.get(k));}System.out.println();//2.迭代器Iterator it1 = keys.iterator();while(it1.hasNext()){Object s = it1.next();System.out.println(s+" - "+m1.get(s));}System.out.println();//3.lambda表达式keys.forEach(str ->{System.out.println(str + " - "+m1.get(str));});}
}

法二 获取每个键值对,再getKey ,getValue

entrySet()

public class map遍历02_entrySet {public static void main(String[] args) {Map<String,Integer> m1 = new HashMap();m1.put("zhangsan",100);m1.put("lisi",99);m1.put("wangwu",98);m1.put("maliu",97);Set<Map.Entry<String,Integer>> setentry = m1.entrySet();//接下来就是三种遍历,和keySet一样的for(Map.Entry<String,Integer> e1 : setentry){String k = e1.getKey();Integer v = e1.getValue();System.out.println(k+" - "+v);}System.out.println();//迭代器Iterator<Map.Entry<String,Integer>> it = setentry.iterator();while(it.hasNext()){Map.Entry<String,Integer> tmp = it.next();String k = tmp.getKey();Integer v = tmp.getValue();System.out.println(k+" - "+v);}System.out.println();//lamdba表达式setentry.forEach(tmp ->{String k = tmp.getKey();Integer v = tmp.getValue();System.out.println(k+" - "+v);});}
}

法三:lambda表达式,利用Map的forEach方法

public class Map遍历03_lambda {public static void main(String[] args) {Map<String,Integer> m1 = new HashMap();m1.put("zhangsan",100);m1.put("lisi",99);m1.put("wangwu",98);m1.put("maliu",97);//利用forEach可以直接进行遍历m1.forEach(new BiConsumer<String, Integer>() {@Overridepublic void accept(String k, Integer v) {System.out.println(k+" - "+v);}});System.out.println();//lambda表达式改进m1.forEach((k,v)->{System.out.println(k+" - "+v);});}
}

4.4  HashMap

  1. Map 接口的常用实现类:HashMap、Hashtable、Properties;
  2. HashMap 是 Map 接口使用频率最高的实现类;
  3. HashMap 是以 key - value 对的形式来存储的;
  4. key 不能重复添加,但value可以,都允许使用null;
  5. 如果添加相同的 key,则会覆盖原来的 key - value,等同于修改;
  6. 与 HashSet一样,不保证映射的顺序,因为底层是以哈希表的方式来存储的;
  7. HashMap 没有实现同步,所以线程不安全;

HashMap的用法以及扩容机制和C++中的unorded_map是一样的

利用HashMap来统计80个同学对四个景点的意向

public class HashMap01 {public static void main(String[] args) {//1.先来定义几个景点String[] s = new String[]{"A","B","C","D"};//2.定义一个HashMapHashMap<String,Integer> hm = new HashMap<>();//3.用随机数模拟同学们的投票Random r = new Random();for(int i=0;i<80;++i){int index = r.nextInt(s.length);if(hm.containsKey(s[index])){//已经插入过了int count = hm.get(s[index]);count++;hm.put(s[index],count);}else{//第一次插入hm.put(s[index],1);}}//4.将HashMap的结果输出System.out.println(hm);//5.遍历求最多的那个int res = 0;Set<String> entry = hm.keySet();for(String str : entry){int tmp = hm.get(str);res = Math.max(res,tmp);}System.out.println(res);System.out.println();Set<Map.Entry<String, Integer>> entries = hm.entrySet();for(Map.Entry<String,Integer> e : entries){res = Math.max(res,e.getValue());}System.out.println(res);}
}

4.5 LinkedHashMap

4.6 TreeMap

这和C++当中的Map是几乎一样的。

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

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

相关文章

Python【Matplotlib】图例可拖动改变位置

代码&#xff1a; import matplotlib.pyplot as plt from matplotlib.widgets import Button# 创建一个示例图形 fig, ax plt.subplots() line, ax.plot([1, 2, 3], labelLine 1)# 添加图例 legend ax.legend(locupper right, draggableTrue)# 添加一个按钮&#xff0c;用于…

mybatis动态SQL-sql片段

1、建库建表 create database mybatis-example; use mybatis-example; create table emp (empNo varchar(40),empName varchar(100),sal int,deptno varchar(10) ); insert into emp values(e001,张三,8000,d001); insert into emp values(e002,李四,9000,d001); insert into…

简单电子报警器设计与制作方法

简单电子报警器设计与制作方法 注&#xff1a; 1、按上图连接好。 2、改变R&#xff58;的大小即使基极电路的电流发生改变&#xff0c;使频率发生改变。 3、增大电容&#xff0c;有利于低音向第一个三极管的基极反馈&#xff0c;因此最终 输出频率变低。 4、R2处接光敏电阻…

数据结构和算法-AOV与AOE网络和(逆)拓扑排序与关键路径

文章目录 AOV网络拓扑排序代码实现时间复杂度 逆拓扑排序实现DFS算法实现逆拓扑排序小结 AOE网络关键路径求关键路径求事件最早发生时间求事件最迟发生时间求活动最早发生时间求活动最迟发生时间求活动余量 关键活动 关键路径的特性小结 AOV网络 必须是DAG图&#xff08;有向无…

本科论文降重修改技巧 神码ai

大家好&#xff0c;今天来聊聊本科论文降重修改技巧&#xff0c;希望能给大家提供一点参考。 以下是针对论文重复率高的情况&#xff0c;提供一些修改建议和技巧&#xff0c;可以借助此类工具&#xff1a; 本科论文降重修改技巧 对于本科论文的写作&#xff0c;降重修改是一个…

飞天使-docker知识点6-容器dockerfile各项名词解释

文章目录 docker的小技巧dockerfile容器为什么会出现启动了不暂停查看docker 网桥相关信息 docker 数据卷 docker的小技巧 [rootlight-test playbook-vars[]# docker inspect -f "{{.NetworkSettings.IPAddress}}" d3a9ae03ae5f 172.17.0.4docker d3a9ae03ae5f:/etc…

【idea】解决sprintboot项目创建遇到的问题

目录 一、报错Plugin ‘org.springframework.boot:spring-boot-maven-plugin:‘ not found 二、报错java: 错误: 无效的源发行版&#xff1a;17 三、java: 无法访问org.springframework.web.bind.annotation.CrossOrigin 四、整合mybatis的时候&#xff0c;报java.lang.Ill…

电子元器件介绍——二极管(四)

电子元器件介绍 文章目录 电子元器件介绍前言一、二极管的基础知识二、二极管的分类三、二极管的应用总结 前言 这一节我们看一下二极管。 一、二极管的基础知识 PN结&#xff1a;是指一块半导体单晶&#xff0c;其中一部分是P型区&#xff0c;其余部分是N型区。 在电场作用…

听GPT 讲Rust源代码--src/tools(14)

File: rust/src/tools/rust-analyzer/crates/cfg/src/lib.rs 在Rust源代码中&#xff0c;rust/src/tools/rust-analyzer/crates/cfg/src/lib.rs这个文件是Rust语言分析器&#xff08;Rust Analyzer&#xff09;的一部分&#xff0c;用于处理和管理条件编译指令&#xff08;Cond…

打破涨粉瓶颈!如何通过视频号找热门话题?

如果你正在运营视频号&#xff0c;相信你一定会遇到这样的瓶颈&#xff0c;视频号播放不理想&#xff0c;牟足劲想涨几个粉丝&#xff0c;结果还掉粉了&#xff1f;今天我们就聊聊如何通过视频号找热门话题! 当你的播放和粉丝增长停滞 数据不好的的时候需要更新迭代 同时还需…

DeciLM-7B:突破极限,高效率、高精准度的70亿参数AI模型

引言 在人工智能领域&#xff0c;语言模型的发展速度令人瞩目。Deci团队最近推出了一款具有革命性意义的语言模型——DeciLM-7B。这款模型在速度和精确度上都实现了显著的突破&#xff0c;以其70亿参数的规模&#xff0c;在语言模型的竞争中脱颖而出。 Huggingface模型下载&am…

torch中张量与数据类型的介绍

PyTorch张量的定义介绍 PyTorch最基本的操作对象是张量&#xff0c;它表示一个多维数组&#xff0c;类似NumPy的数组&#xff0c;但是前者可以在GPU上加速计算 初始化张量 ttorch.tensor([1,2]) # 创建一个张量 print(t) t.dtype #打印t的数据类型为torch.int…

尺度函数与小波函数

尺度函数与小波函数 尺度函数 设存在函数 φ j , k ( x ) 2 j / 2 φ ( 2 j x − k ) \varphi_{j,k}(x)2^{j/2}\varphi(2^{j}x-k) φj,k​(x)2j/2φ(2jx−k) 对所有的 j j j, k ∈ Z k{\in}\mathbb{Z} k∈Z 和 φ ( x ) ∈ L 2 ( R ) \varphi(x){\in}L^2(R) φ(x)∈L2(R)…

为什么Apache Doris适合做大数据的复杂计算,MySQL不适合?

为什么Apache Doris适合做大数据的复杂计算&#xff0c;MySQL不适合&#xff1f; 一、背景说明二、DB架构差异三、数据结构差异四、存储结构差异五、总结 一、背景说明 经常有小伙伴发出这类直击灵魂的疑问&#xff1a; Q&#xff1a;“为什么Apache Doris适合做大数据的复杂计…

大数据与深度挖掘:如何在数字营销中与研究互动

数字营销最吸引人的部分之一是对数据的内在关注。 如果一种策略往往有积极的数据&#xff0c;那么它就更容易采用。同样&#xff0c;如果一种策略尚未得到证实&#xff0c;则很难获得支持进行测试。 数字营销人员建立数据信心的主要方式是通过研究。这些研究通常分为两类&…

【教3妹学编程-算法题】找出峰值

3妹&#xff1a;2哥2哥&#xff0c;你有没有看到新闻&#xff1a;北京地铁事故中102人骨折&#xff01; 2哥 : 看到了&#xff0c;没想到坐个地铁还出事故了。 3妹&#xff1a;事故原因为雪天轨滑导致前车信号降级&#xff0c;紧急制动停车&#xff0c;后车因所在区段位于下坡地…

【️Java是值传递还是引用传递?】

✅Java是值传递还是引用传递&#xff1f; ✅Java是值传递还是引用传递&#xff1f;✅典型理解 ✅增加知识仓✅Java的求值策略✅Java中的对象传递✅值传递和共享对象传递的现象冲突吗? ✅总结 ✅Java是值传递还是引用传递&#xff1f; ✅典型理解 编程语言中需要进行方法间的…

kafka学习笔记--Kafka副本

本文内容来自尚硅谷B站公开教学视频&#xff0c;仅做个人总结、学习、复习使用&#xff0c;任何对此文章的引用&#xff0c;应当说明源出处为尚硅谷&#xff0c;不得用于商业用途。 如有侵权、联系速删 视频教程链接&#xff1a;【尚硅谷】Kafka3.x教程&#xff08;从入门到调优…

比特币即自由

号外&#xff1a;教链内参12.15《疯狂的铭文》 文 | Ross Ulbricht. 原文标题&#xff1a;Bitcoin Equals Freedom. 2019.9.25 在中本聪发明比特币后的头一年左右&#xff0c;发生了一些特别的事情&#xff0c;不仅没有人预料到&#xff0c;甚至很多人认为不可能。试着想象一下…

昇腾Profiling性能分析工具使用问题案例

昇腾Profiling性能分析工具用于采集和分析运行在昇腾硬件上的AI任务各个运行阶段的关键性能指标, 用户可根据输出的性能数据&#xff0c;快速定位软、硬件性能瓶颈&#xff0c;提升AI任务性能分析的效率。具体使用方法请参考&#xff1a; 本期分享几个关于Profiling性能分析工具…