1.面试官:如何实现 List 集合去重?
2.HashSetï¼TreeSetåLinkedHashSetçåºå«
3.java库里的码详有顺序的set?
4.Java_LinkedHashSet
5.List 去除重复数据的 5 种正确姿势!
6.java的码详LinkedHashSet是怎样实现存取有序的, 底层原理是什么
面试官:如何实现 List 集合去重?
在进行Java面试时,面试官常会问到如何实现List集合去重。码详本文将详细介绍三种实现方法。码详
方法一:自定义去重
有两种实现方式。码详首先,码详开源 his bs 源码创建一个新集合,码详遍历原集合,码详若元素不在新集合中,码详则插入,码详否则忽略。码详代码如下:
运行结果可见,码详新集合中无重复元素。码详
方法二:自定义去重(改进版)
使用迭代器循环,码详判断当前元素首次出现与最后出现位置是码详否相等,不等则为重复元素,删除。代码如下:
运行结果同样可见,好论坛系统源码新集合中无重复元素。
方法三:利用Set集合去重
Set集合具有去重特性,传递List集合创建Set集合,即可实现数据转移和去重。代码如下:
运行结果表明,元素顺序发生变化。为解决此问题,使用LinkedHashSet,代码如下:
运行结果显示,去重同时保持原有顺序。
方法四:使用Stream去重
利用JDK 8提供的Stream中的distinct方法,可直接实现集合去重。代码如下:
运行结果与方法三结果相同,去重后顺序不变。
总结
本文介绍了三种实现List集合去重的方法。自定义实现虽然复杂,但灵活性强。bias突破公式源码Set集合去重简单方便,但顺序改变。Stream的distinct方法简洁高效,无需创建新集合,是首选方法。通过本文,您应能熟练掌握List集合去重的多种实现方式。
HashSetï¼TreeSetåLinkedHashSetçåºå«
HashSet
HashSetæ以ä¸ç¹ç¹
ä¸è½ä¿è¯å ç´ çæå顺åºï¼é¡ºåºæå¯è½åçåå
ä¸æ¯åæ¥ç
éåå ç´ å¯ä»¥æ¯null,ä½åªè½æ¾å ¥ä¸ä¸ªnull
å½åHashSetç»åä¸åå ¥ä¸ä¸ªå ç´ æ¶ï¼HashSetä¼è°ç¨è¯¥å¯¹è±¡çhashCode()æ¹æ³æ¥å¾å°è¯¥å¯¹è±¡çhashCodeå¼ï¼ç¶åæ ¹æ® hashCodeå¼æ¥å³å®è¯¥å¯¹è±¡å¨HashSetä¸åå¨ä½ç½®ã
LinkedHashSet
LinkedHashSetéååæ ·æ¯æ ¹æ®å ç´ çhashCodeå¼æ¥å³å®å ç´ çåå¨ä½ç½®ï¼ä½æ¯å®åæ¶ä½¿ç¨é¾è¡¨ç»´æ¤å ç´ ç次åºãè¿æ ·ä½¿å¾å ç´ çèµ· æ¥åæ¯ä»¥æå ¥é¡ºåºä¿åçï¼ä¹å°±æ¯è¯´ï¼å½éå该éåæ¶åï¼LinkedHashSetå°ä¼ä»¥å ç´ çæ·»å 顺åºè®¿é®éåçå ç´ ã
LinkedHashSetå¨è¿ä»£è®¿é®Setä¸çå ¨é¨å ç´ æ¶ï¼æ§è½æ¯HashSet好ï¼ä½æ¯æå ¥æ¶æ§è½ç¨å¾®éè²äºHashSetã
TreeSetç±»
TreeSetæ¯SortedSetæ¥å£çå¯ä¸å®ç°ç±»ï¼TreeSetå¯ä»¥ç¡®ä¿éåå ç´ å¤äºæåºç¶æãTreeSetæ¯æ两ç§æåºæ¹å¼ï¼èªç¶æåº åå®å¶æåºï¼å ¶ä¸èªç¶æåºä¸ºé»è®¤çæåºæ¹å¼ãåTreeSetä¸å å ¥çåºè¯¥æ¯åä¸ä¸ªç±»ç对象ã
TreeSetå¤æ两个对象ä¸ç¸ççæ¹å¼æ¯ä¸¤ä¸ªå¯¹è±¡éè¿equalsæ¹æ³è¿åfalseï¼æè éè¿CompareToæ¹æ³æ¯è¾æ²¡æè¿å0
java库里的有顺序的set?
当你在Java库中寻找一个有顺序的Set时,LinkedHashSet是一个理想的选择。这个Set的迭代顺序与插入顺序相同,满足了你需要有序集合的需求。
然而,需要注意的是,Set没有提供根据索引来访问元素的方法。因此,如果你的需求是基于索引的访问,那么List将更符合预期。电脑屏幕适配源码在使用之前,可以先判断目标元素是否存在,避免不必要的插入操作。
如果你希望在代码中实现一个自定义的、支持去重的List,可以将HashSet与ArrayList相结合,利用HashSet的无重复元素特性,同时保持List的顺序。
另外,如果你的项目需求更为复杂,对性能和功能有更高的要求,可以考虑使用楼上的ListOrderedSet。这个类需要你下载Commons Collections包,它可以提供更高级的集合操作,满足在有序集合中进行复杂迭代和查找的需求。
Java_LinkedHashSet
LinkedHashSet是HashSet的子类,同样存在于util包中,开放组织的源码需要导入使用。
LinkedHashSet继承了HashSet,但它与HashSet存在一定的区别。
LinkedHashSet的底层结构是数组+链表/红黑树+链表,通过额外的链表来记录元素的顺序,这使得LinkedHashSet是有序的。而HashSet则没有这种链表,是无序的。两者的共同点是都不允许存储重复的元素。
使用LinkedHashSet时,其存入的顺序即为输出顺序,如所示。而HashSet由于无序,输出顺序是随机的。
List 去除重复数据的 5 种正确姿势!
在Java中,有五种常见的方法可以用于从ArrayList中移除重复数据。以下是这些方法的详细介绍: 1. 利用LinkedHashSet: LinkedHashSet是高效去重的选择,它保证了元素的顺序并自动去除重复。在示例中,创建一个LinkedHashSet,然后将ArrayList的内容转换回列表,即可得到无重复的列表。以下是相关代码示例:java
List numbersList = ...; // 你的列表
List listWithoutDuplicates = new ArrayList>(new LinkedHashSet>(numbersList));
2. Java 8 Stream API: 使用stream的distinct()方法,结合equals()方法,可轻松去重。代码如下:java
List listWithoutDuplicates = numbersList.stream().distinct().collect(Collectors.toList());
3. HashSet特性利用: 通过HashSet的无重复特性,我们可以用它作为判断条件,但需要注意HashSet不保证顺序。这种方法需要两次遍历。java
private static void removeDuplicate(List list) {
HashSet set = new HashSet>(list.size());
// ...
}
4. 利用contains方法: 利用List的contains()方法,遍历列表,只添加未出现过的元素。java
private static void removeDuplicate(List list) {
List result = new ArrayList>(list.size());
// ...
}
5. 双重for循环: 通过比较每个元素,移除重复项。这种方法效率较低,适用于数据量较小的情况。java
for (int i = 0; i < list.size(); i++) {
for (int j = i + 1; j < list.size(); j++) {
// ...
}
}
选择哪种方法取决于你的具体需求,如对顺序有要求、性能需求、代码简洁性等因素。以上五种方法各有优缺点,可以根据实际情况选择最适合的方法。java的LinkedHashSet是怎样实现存取有序的, 底层原理是什么
LinkedHashSet 的实现对于 LinkedHashSet 而言,它继承与 HashSet、又基于 LinkedHashMap 来实现的。
LinkedHashSet 底层使用 LinkedHashMap 来保存所有元素,它继承与 HashSet,其所有的方法操作上又与 HashSet 相同,因此 LinkedHashSet 的实现上非常简单,只提供了四个构造方法,并通过传递一个标识参数,调用父类的构造器,底层构造一个 LinkedHashMap 来实现,在相关操作上与父类 HashSet 的操作相同,直接调用父类 HashSet 的方法即可。
需要注意理解的点是:
LinkedHashSet 是 Set 的一个具体实现,其维护着一个运行于所有条目的双重链接列表。此链接列表定义了迭代顺序,该迭代顺序可为插入顺序或是访问顺序。
LinkedHashSet 继承与 HashSet,并且其内部是通过 LinkedHashMap 来实现的。有点类似于我们之前说的LinkedHashMap 其内部是基于 Hashmap 实现一样,不过还是有一点点区别的(具体的区别大家可以自己去思考一下)。
如果我们需要迭代的顺序为插入顺序或者访问顺序,那么 LinkedHashSet 是需要你首先考虑的。
JAVA 集合框架(三) Set集合详解和常用方法
Set集合是Java集合框架下的一个接口,它继承自Collection接口,用于表示不允许包含重复元素的集合。集合中的元素无序且唯一,即使添加等效的对象也不会重复存储。本篇文章将深入探讨Set集合的特性,主要实现类HashSet、TreeSet、LinkedHashSet的构造函数与特有方法。
HashSet集合特点主要体现在它使用哈希表作为底层数据结构,用于存储不重复的元素。构造函数提供了多种方式创建HashSet实例,包括无参数构造、带集合参数构造、指定初始容量、指定初始容量与负载因子的构造函数。
TreeSet集合基于红黑树数据结构,提供有序且无重复元素的集合。构造函数包括无参数构造、使用Comparator构造以及包含集合元素的构造函数。
LinkedHashSet集合是HashSet的子类,实现了Set接口。它是哈希表与链表的组合,能够保持元素插入顺序,适用于需要保持元素插入顺序的场景。
本篇内容涵盖了Set集合的主要实现类的构造函数与特有方法,以及它们在不同场景下的应用。通过理解这些构造函数与方法,可以更高效地使用Java集合框架中的Set集合。
javaè¯è¨ä¸,LinkedHashSetçä¼ç¼ºç¹ï¼
讲ä¸LinkedHashSetï¼ä»çä¼ç¹æ¯æç §æå ¥é¡ºåºæåï¼é度ç¥æ ¢\x0d\\x0d\详ç»æè¿°ï¼\x0d\LinkedHashMapåLinkedHashSetæ¯JDK1.4ä¸å¼å ¥ç两个æ°çéåç±»ãè½ç¶å·²ç»è¿å»5å¹´äºï¼ä½ææ¢æèµå¹¶ä¸æ¯å¾å¤äººé½ç¨è¿ï¼å 为æ就没æç¨è¿ï¼ãä½è¿ä¸¤ä¸ªç±»å¨æäºæ åµä¸è¿æ¯é常æç¨çï¼è¿å»æ²¡æç¨ï¼ç°å¨æ²¡æç¨ï¼é½æ²¡æå ³ç³»ãä½è¿æ¯åºè¯¥å¯¹è¿ä¸¤ä¸ªCollectionæ¡æ¶çæ°æåææäºè§£ï¼å 为ä¹è®¸ä»¥åä½ ä¼å°ï¼æè å ¶å®ä½ ç°å¨å°±åºè¯¥è¦ç¨å°ã\x0d\\x0d\LinkedHashMap/LinkedHashSet顾åæä¹ï¼å°±æ¯å¨Hashçå®ç°ä¸æ·»å äºLinkedçæ¯æã对äºHashMap/HashSetçæ¯ä¸ªèç¹ä¸éè¿ä¸ä¸ªé¾è¡¨ä¸²èèµ·æ¥ï¼è¿æ ·å°±å¯ä»¥ä¿è¯ç¡®å®ç顺åºã对äºå¸ææ常éå¤æ度çé«æååæ§è½è¦æ±ï¼åæ¶æè¦æ±æåºçæ åµä¸ï¼ç°å¨å¯ä»¥ç´æ¥ä½¿ç¨LinkedHashMap/Setäºã\x0d\\x0d\对äºLinkedHashMapè¿æä¸ç¹ç¹å«æ³¨æï¼LinkedHashMapæ¯æ两ç§æåºï¼æå ¥é¡ºåºã访é®é¡ºåºãåè æ¯ææç §æå ¥æ¶ç顺åºæåºï¼åè æ¯ææç §ææ§ä½¿ç¨å°æè¿ä½¿ç¨ç顺åºãå³å¦æå¨ä¸ä¸ªLinkedHashMapä¸æ5个èç¹ï¼ç°å¨ç顺åºæ¯e1,e2,e3,e4,e5.å¦ææ¯ä½¿ç¨é¡ºåºçè¯ï¼ç°å¨è®¿é®äºä¸æ¬¡e2,é£ä¹e2èç¹å°ç§»è³é¾è¡¨çå°¾é¨ãç°å¨é¡ºåºå为ï¼e1,e3,e4,e5,e2.\x0d\\x0d\è¿ä¼é æ严éçæ§è½é®é¢åï¼çæ¡å½ç¶æ¯å¦å®çãå 为å¨è¿å¿çé¾è¡¨æä½æ¯å¸¸é级çãè¿ä¹æ¯LinkedHashMap/Setå¨è¿å¿æ¯TreeMap/Setæ§è½æ´é«çåå ã\x0d\\x0d\åæ ·ï¼LinkedHashMap/Setä¹ä¸æ¯thread-safeçãå¦æå¨å¤çº¿ç¨ä¸è®¿é®ï¼æ¯éè¦è¿è¡å¤é¨åæ¥ï¼æè 使ç¨Collections.synchronizedMap()çæ¹æ³å è£ æä¸ä¸ªthread-safeçMap/Setã\x0d\\x0d\ç¹å«éè¦æ³¨æçæ¯ï¼å¨ä½¿ç¨â访é®é¡ºåºâæ¶ï¼è¯»åèç¹æä½ä¹æ¯âç»æååâçæä½ãå 为ï¼è¿ä¼æ¹åå ç´ éåç顺åºãæ以ï¼å¨ä½¿ç¨LinkedHashMapçiterator()æ¹æ³ï¼éåå ç´ æ¶ï¼å¦æå ¶å®çº¿ç¨æ读åæä½ï¼ä¹è¦è¿è¡åæ¥ãå¦åï¼ä¹ä¼æåºåå ¶å®fail-fastä¸æ ·çç±äºå é¤æå¢å æä½èå¼èµ·çCurrentModificationExceptionçä¾å¤ã\x0d\\x0d\LinkedHashMap,HashMapç