17、java中的集合(4)

       之前单列集合只说过了List系列的集合,接下来再说一下Set集合系列,Set集合是无序集合(存取顺序不一致),不允许添加相同元素,Set的实现依赖于Map集合,可以将Set集合看作Map集合键的集合,Map中是不可能包含两个键相同的键值对,所以Set集合不允许相同元素也是为此, Set集合的基本实现类有HashSet、TreeSet、LinkedHashSet等,接下来详细介绍。

       HashSet,其实现依赖于HashMap,操作HashSet中的功能方法到最后都是调用的HashMap中的方法,各个功能方法比较容易理解,其源码如下:


public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, java.io.Serializable
{//底层维护一个HashMap,用于存储数据private transient HashMap<E,Object> map;// 虚拟值,以与备份映射中的对象关联private static final Object PRESENT = new Object();//-----------------------构造方法-----------------------////构造HashSet就相当于实例化HashMappublic HashSet() {map = new HashMap<>();}public HashSet(int initialCapacity, float loadFactor) {map = new HashMap<>(initialCapacity, loadFactor);}public HashSet(int initialCapacity) {map = new HashMap<>(initialCapacity);}//保证有序HashSet(int initialCapacity, float loadFactor, boolean dummy) {map = new LinkedHashMap<>(initialCapacity, loadFactor);}//-----------------------功能方法-----------------------////迭代器public Iterator<E> iterator() {return map.keySet().iterator();}//添加方法,其实是给map添加一个键值对,键是添加的元素,值是一个虚拟值,用于组合构建键值对public boolean add(E e) {return map.put(e, PRESENT)==null;}//删除方法,调用的是map中根据key删除键值对的方法public boolean remove(Object o) {return map.remove(o)==PRESENT;} 
}

       TreeSet集合和LinkedHashSet分别依赖于TreeMap集合和LinkedHashMap集合,Map集合中对双列集合的功能方法,在set集合中对单列集合均可使用。

       为了方便操作集合,java提供了一个工具类Collections,类中定义多个静态方法用来直接操作集合可以实现集合的排序、查找、复制、替换、截取等。

       最后说一下遍历集合的一些方式,代码如下:

public static void main(String[] args) {List<String> list = new ArrayList<String>();list.add("aaa");list.add("bbb");list.add("ccc");//方式一:遍历集合,然后根据下标获取到每一个位置上的元素,以完成遍历for (int i = 0; i < list.size(); i++) {System.out.println("方式一:"+list.get(i));}//方式二:使用foreach,俗称增强for循环for (String string : list) {System.out.println("方式二:"+string);}//方式三:使用迭代器//实现原理如下边迭代器实现代码Iterator<String> iterator = list.iterator();while (iterator.hasNext()) {//list.add(2, "555");//报错System.out.println("方式三:"+iterator.next());}System.out.println("---------------------------------------------------");Map<String, Object> map = new HashMap<String, Object>();map.put("111", "aaa");map.put("222", "bbb");map.put("333", "ccc");//方式一:通过map内部方法将map中的元素封装到一个Set中,Set中元素的类型确定: Set<Entry<String, Object>>//然后使用Entry类中的方法+set集合遍历来遍历map集合Set<Entry<String, Object>> entrySet = map.entrySet();for (Entry<String, Object> entry : entrySet) {System.out.println("方式一:"+entry.getValue());}//方式二:获取map集合中key的集合,然后根据key获取对应value值Set<String> keySet = map.keySet();for (String key : keySet) {System.out.println("方式二:"+map.get(key));}}-----------------------------迭代器实现代码-----------------------------------
//单列集合都实现了Iterable接口,所以需要实现迭代方法iterator
public interface Iterable<T> {  Iterator<T> iterator(); 
}//使用ArrayList中的迭代器实现为例
public Iterator<E> iterator() {return new Itr();}//迭代器的具体实现
private class Itr implements Iterator<E> {int cursor; // 记录下一个要返回元素的索引      int lastRet = -1; int expectedModCount = modCount;// 修改次数,用来记录修改的次数是否发生了变化//判断是否还有下一个元素public boolean hasNext() {return cursor != size;}//检查集合列表是否被修改,在使用迭代器遍历集合时不允许使用集合方法修改集合内容,否则报错final void checkForComodification() {if (modCount != expectedModCount)throw new ConcurrentModificationException();}//获取到下一个返回的元素public E next() {checkForComodification();int i = cursor;if (i >= size)throw new NoSuchElementException();//获取到ArrayList集合底层维护的那个存储数据的数组,也就是获取到数组的一个副本//这也是为什么使用迭代器遍历时不能修改集合的原因,操作的是副本Object[] elementData = ArrayList.this.elementData;if (i >= elementData.length)throw new ConcurrentModificationException();cursor = i + 1;return (E) elementData[lastRet = i];}//迭代器中提供了一个remove方法,可用于迭代时删除元素public void remove() {if (lastRet < 0)throw new IllegalStateException();checkForComodification();try {ArrayList.this.remove(lastRet);cursor = lastRet;lastRet = -1;expectedModCount = modCount;} catch (IndexOutOfBoundsException ex) {throw new ConcurrentModificationException();}}
}

集合的基本使用到这里也就介绍完了。

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

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

相关文章

U92904-画地为佬【二分,结论】

正题 题目链接:https://www.luogu.org/problem/U92904?contestId23574 题目大意 用mmm根长度为1的火柴求能够圈住的最多块的地。 解题思路 显然如果刚好能够围成一个正方形那么一定是最优的&#xff0c;那么我们先将能够围成的围成一个最大的正方形&#xff0c;然后剩下的在…

确保线程安全下使用Queue的Enqueue和Dequeue

场景是这样&#xff0c;假设有一台设备会触发类型为Alarm的告警信号&#xff0c;并把信号添加到一个Queue结构中&#xff0c;每隔一段时间这个Queue会被遍历检查&#xff0c;其中的每个Alarm都会调用一个相应的处理方法。问题在于&#xff0c;检查机制是基于多线程的&#xff0…

2017西安交大ACM小学期数据结构 [分块、二维矩阵]

Problem B 发布时间: 2017年6月28日 10:06 最后更新: 2017年6月28日 16:35 时间限制: 2000ms 内存限制: 32M 描述 给定一个nm的矩形, 其中第i行第j列的值为ai,j给出q个操作, 操作有两种 对于形如1x1y1x2y2z的操作, 将(x1,y1)-(x2,y2)这段矩形区域的所有元素加上z, 满足1≤…

18、java中的泛型

之前介绍集合时&#xff0c;可以看到有List<String>这样的写法&#xff0c;那么尖括号里的内容是什么呢&#xff1f;这是泛型&#xff0c;意思就是说声明的这个List集合只能存放String类型的元素。 泛型是什么&#xff1f; ‘泛’指一般、不深入&#xff0c;在这里可以认…

编写一个Java程序,其中包含三个线程: 厨师(Chef)、服务员(Waiter)和顾客(Customer)

编写一个Java程序&#xff0c;其中包含三个线程: 厨师(Chef)、服务员(Waiter)和顾客(Customer)。他们的行动如下: 厨师准备菜肴&#xff0c;每次准备一个。服务员等待菜肴准备好&#xff0c;然后将其送到顾客那里。顾客等待服务员送来菜看后才开始吃。所有三个角色应该循环进行…

U86650-群鸡乱舞【矩阵乘法】

正题 题目链接:https://www.luogu.org/problem/U86650?contestId23574 题目大意 第一年有nnn只鸡&#xff0c;每只大于等于两岁的鸡每年可以生一只&#xff0c;在ttt岁时不会生鸡而会暴毙。 现在给出每只鸡的年龄&#xff0c;求第mmm年鸡的总数量。 解题思路 用fif_{i}fi​…

2017西安交大ACM小学期数据结构 [线段树]

Problem B 发布时间: 2017年7月1日 02:08 最后更新: 2017年7月1日 02:10 时间限制: 1000ms 内存限制: 64M 描述 给定一个长度为n的序列a1, a2, ..., an, 满足这个序列是一个1~n的排列 如果一个序列满足: 将序列排序后, 任意两个相邻的元素的差为1, 那么就称这个序列为&qu…

19、java中枚举

枚举是什么&#xff1f; 枚举就是将一个有限集合中的所有元素列举出来&#xff0c;在java中使用可以使用enum关键字来声明一个枚举类。 为什么使用枚举&#xff1f; 之前当用到一些常量时&#xff0c;便临时声明一个&#xff0c;这样使得代码看起来很乱&#xff0c;这里一个…

Hangfire使用ApplicationInsigts监控

起因我司目前使用清真的ApplicationInsights来做程序级监控。&#xff08;ApplicationInsights相关文档: https://azure.microsoft.com/zh-cn/services/application-insights/ &#xff09;其实一切都蛮好的&#xff0c;但是我们基于Hangfire的Job系统却无法被Ai所监控到&#…

nssl1446-小智的旅行【dp】

正题 题目大意 求一条最大的权值严格上升的路径。 解题思路 将边权排序&#xff0c;然后从fxf_xfx​转移到fy1f_y1fy​1即可&#xff0c;要注意的是因为严格上升&#xff0c;所以此次转移用的fff不能是相同权值转移时转移的。 codecodecode #include<cstdio> #include…

2017西安交大ACM小学期数据结构 [树状数组]

Problem C 发布时间: 2017年6月28日 11:38 最后更新: 2017年6月28日 16:38 时间限制: 1000ms 内存限制: 32M 描述 给定一个长度为n的序列a1, a2, ..., an, 其中ai∈[1,10]给出q个操作, 操作分为两种 对于形如1xy的操作, 将ax改为y, 满足1≤x≤n, 1≤y≤10对于形如2xyz的操…

NET主流ORM框架分析

接上文我们测试了各个ORM框架的性能&#xff0c;大家可以很直观的看到各个ORM框架与原生的ADO.NET在境删改查的性能差异。这里和大家分享下我对ORM框架的理解及一些使用经验。ORM框架工作原理所有的ORM框架的工作原理都离不开下面这张图&#xff0c;只是每个框架的实现程度不同…

20、java中的类加载机制

1、类加载机制是什么&#xff1f; 类加载机制指的就是jvm将类的信息动态添加到内存并使用的一种机制。 2、那么类加载的具体流程是什么呢&#xff1f; 一般说类加载只有三步&#xff1a;加载、连接和初始化&#xff0c;其中连接包括验证、准备和解析&#xff0c;用于将运行时加…

nssl1447-小智的糖果【dp】

正题 题目大意 长度为nnn的序列&#xff0c;mmm个位置要求两边都比他大&#xff0c;kkk个位置要求两边都比他小。求序列个数。 解题思路 若第xxx个位置为山峰&#xff0c;那么ax−1<ax>ax1a_{x-1}<a_x>a_{x1}ax−1​<ax​>ax1​&#xff0c;我们用upiup_iu…

21、java中的反射机制

先推荐安装一个 eclipse 的反编译插件 Enhanced Class Decompiler 是什么&#xff1f; 在说反射之前先说一下编译时类型和运行时类型&#xff0c;大家都知道List是一个接口&#xff0c;它是不可以被实例化的&#xff0c;但是可以通过多态实现&#xff1a;List list new Arra…

【北京】BXUG第12期活动基于 .NET Core构建微服务和Xamarin

分享主题&#xff1a;基于 .NET Core构建微服务实战分享分享者&#xff1a;薛锋 北京切尔思科技架构师 兼任东北大学信息安全工程师和技术主播&#xff0c;行业内专注于研究 .NET Core和Web应用&#xff0c;具有比较扎实的技术基础和数年的从业经历。在GitHub上主持数个开…

2017西安交大ACM小学期数据结构 [树状数组,极大值]

Problem D 发布时间: 2017年6月28日 10:51 最后更新: 2017年6月28日 16:38 时间限制: 1000ms 内存限制: 32M 描述 给定一个长度为n的序列a1, a2, ..., an当k满足2≤k≤n−1, ak>ak−1且ak>ak1时, 将元素k称为极大值点, 给出q个操作, 操作分为两种 对于形如1xy的操作…

nssl1448-小智过马路【模拟】

正题 题目大意 nnn个横向道&#xff0c;若干辆车&#xff0c;每辆车速度恒定&#xff0c;给出方向位置长度。 过马路的速度&#xff0c;最早开始时间&#xff0c;最晚开始时间。求最长的可以通过马路的时间段。 解题思路 计算出每辆车限制的时间区间&#xff0c;然后排序找到…

22、java中的注解

注解是什么&#xff1f; 注解可以理解成注释、标记、标签的意思&#xff0c;用来标记类、方法等。就相当于现实生活中的一些事物&#xff0c;上边贴一个标签或者写一些注释性文字来描述它可以用来做什么、怎么用、何时用等信息。Java中的注解也是一样的&#xff0c;用来表示被标…

谈谈ASP.NET Core中的ResponseCaching

前言前面的博客谈的大多数都是针对数据的缓存&#xff0c;今天我们来换换口味。来谈谈在ASP.NET Core中的ResponseCaching&#xff0c;与ResponseCaching关联密切的也就是常说的HTTP缓存。在阅读本文内容之前&#xff0c;默认各位有HTTP缓存相关的基础&#xff0c;主要是Cache-…