文档章节

Java中的Set集合类

谢思华
 谢思华
发布于 2015/06/10 12:11
字数 1350
阅读 1577
收藏 0

1.概述

Java 中的Set和正好和数学上直观的集(set)的概念是相同的。Set最大的特性就是不允许在其中存放的元素是重复的。Set 可以被用来过滤在其他集合中存放的元素,从而得到一个没有包含重复新的集合。


2.常用方法

按照定义,Set 接口继承 Collection 接口,而且它不允许集合中存在重复项。所有原始方法都是现成的,没有引入新方法。具体的 Set 实现类依赖添加的对象的 equals() 方法来检查等同性。

        各个方法的作用描述:

        public int size() :返回set中元素的数目,如果set包含的元素数大于Integer.MAX_VALUE,返回Integer.MAX_VALUE;

        public boolean isEmpty() :如果set中不含元素,返回true ;

        public boolean contains(Object o) :如果set包含指定元素,返回true ;

        public Iterator iterator() : 返回set中元素的迭代器,元素返回没有特定的顺序,除非set提高该保证的某些类的实例 ;

        public boolean add(Object o) :如果set中不存在指定元素,则向set加入 ;

        public boolean addAll(Collection c) :过滤集合中的重复元素,向set加入 【将c中所有元素添加到Set中,如果Set中已有某一元素,则不添加,因Set不允许有重复值】;

        public boolean remove(Object o) :如果set中存在指定元素,则从set中删除 ;

        public boolean removeAll(Collection c) :如果set包含指定集合,则从set中删除指定集合的所有元素 ;

        public void clear() :从set中删除所有元素;


3.原理分析

HashSet的元素存放顺序和添加进去时候的顺序没有任何关系【HashSet类按照哈希算法来存取集合中的对象,存取速度比较快】【允许包含值为null的元素,但最多只能有一个null元素】;

LinkedHashSet 保持元素的添加顺序;

TreeSet则是对Set中的元素进行排序存放【TreeSet类实现了SortedSet接口,能够对集合中的对象进行排序】。 

(这一点与map很相似:http://my.oschina.net/xsh1208/blog/405747  )        

        一般来说,当要从集合中以有序的方式抽取元素时,TreeSet 实现就会有用处。为了能顺利进行,添加到 TreeSet 的元素必须是可排序的。 而同样需要对添加到TreeSet中的类对象实现 Comparable 接口的支持。对于Comparable接口的实现。假定一棵树知道如何保持 java.lang 包装程序器类元素的有序状态。一般说来,先把元素添加到 HashSet,再把集合转换为 TreeSet 来进行有序遍历会更快。这点和HashMap的使用非常的类似。 

        其实,Set的实现原理是基于Map的。Set中很多实现类和Map中的一些实现类的使用上非常的相似。Map中的“键值对”,其中的 “键”是不能重复的。这个和Set中的元素不能重复一致,其实Set利用的就是Map中“键”不能重复的特性来实现的。 HashSet的巧妙实现:就是建立一个“键值对”,“键”就是我们要存入的对象,“值”则是一个常量。这样可以确保, 我们所需要的存储的信息之是“键”。而“键”在Map中是不能重复的,这就保证了我们存入Set中的所有的元素都不重复。而判断是否添加元素成功,则是通 过判断我们向Map中存入的“键值对”是否已经存在,如果存在的话,那么返回值肯定是常量:PRESENT ,表示添加失败。如果不存在,返回值就为null 表示添加成功。


4.利用Java Set去除重复object

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
 * 类描述:set集合针对String 类型和8大基础数据类型  过滤掉重复数据,如果存放的是其他类型对象,则需要重写hashCode方法和equals方法,当equals 比较相等时,则会去比较hashCode值 hashCode的值 如果一致的话,则不会存进set
 */
public class SetDemo {

public static void main(String[] args) {
Set<String> nameSet = new HashSet<String>();
nameSet.add("张三");
nameSet.add("李四");
nameSet.add("王五");
nameSet.add("张三");

// 输出结果 张三李四王五
for(String name : nameSet){
System.out.print(name + "\t");
}

// List集合去除重复基础数据
List<String> nameList = new ArrayList<String>();
nameList.add("张三");
nameList.add("李四");
nameList.add("王五");
nameList.add("赵六");
nameSet.addAll(nameList);

// 输出结果 张三李四王五赵六
for(String name : nameSet){
System.out.print(name + "\t");
}

// 去除编号和用户名一样的 对象,需要重写 equals 方法 和 hashCode方法
User admin = new User(1, "admin");
User user = new User(2, "user");
User user1 = new User(2, "user");
User admin1 = new User(3, "admin");

Set<User> userSet = new HashSet<User>();
userSet.add(admin);
userSet.add(user);
userSet.add(admin1);
userSet.add(user1);

// 输入结果 admin1admin3user2
for(User u : userSet){
System.out.print(u.username + u.id + "\t");
}
System.out.println(user.equals(null));
}
}

class User{
protected Integer id;
protected String username;
public User(Integer id, String username){
this.id = id;
this.username = username;
}

/**
 * 如果对象类型是User 的话 则返回true 去比较hashCode值
 */
@Override
public boolean equals(Object obj) {
if(obj == null) return false;
if(this == obj) return true;
if(obj instanceof User){ 
User user =(User)obj;
//if(user.id = this.id) return true; // 只比较id
// 比较id和username 一致时才返回true 之后再去比较 hashCode
if(user.id == this.id && user.username.equals(this.username)) return true;
}
return false;
}

/**
 * 重写hashcode 方法,返回的hashCode 不一样才认定为不同的对象
 */
@Override
public int hashCode() {
//return id.hashCode(); // 只比较id,id一样就不添加进集合
return id.hashCode() * username.hashCode();
}

}


© 著作权归作者所有

共有 人打赏支持
谢思华
粉丝 60
博文 202
码字总数 132245
作品 0
广州
程序员
-1-0 Java 简介 java是什么 java简单介绍

Java是一门纯粹的面向对象的高级的平台无关的编程语言 官网介绍: 了解 Java 技术 https://www.java.com/zh_CN/about/ 推荐词条: https://zh.wikipedia.org/wiki/Java https://zh.wikipedia.o...

noteless
07/03
0
0
[Java 并发编程] 集合框架之 同步容器类 & 并发容器类

吾生也有涯,而知也无涯。———《庄子》 通过上一篇文章,我们已经知道设计一个线程安全类的原则和步骤,以及在设计过程中我们应当注意的细节。实际上,Java 的集合库包含了线程安全集合和非...

seaicelin
05/25
0
0
kotlin学习笔记-异常好玩的list集合总结

不积跬步无以至千里,不积小流无以成江海 先看看Kotlin中for循环的遍历 kotlin和Java中的集合工具类 Java中集合及其工具类 Kotlin中Java中集合及其工具类 List MutableList Set MutableSet Ma...

codeGoogle
07/16
0
0
HashMap和Hashtable的区别

HashMap和Hashtable的比较是Java面试中的常见问题,用来考验程序员是否能够正确使用集合类以及是否可以随机应变使用多种思路解决问题。HashMap的工作原理、ArrayList与Vector的比较以及这个问...

LCZ777
2014/03/29
0
0
强悍!Java 9 中的9个新特性

来源:www.oschina.net/translate/java-9-new-features Java 8 发布三年多之后,即将快到2017年7月下一个版本发布的日期了。 你可能已经听说过 Java 9 的模块系统,但是这个新版本还有许多其...

java技术栈
02/02
0
0

没有更多内容

加载失败,请刷新页面

加载更多

arts-week10

Algorithm 905. Sort Array By Parity - LeetCode Review Who’s Afraid of the Big Bad Preloader? 一文读懂前端缓存 一个网络请求3个步骤:请求,处理,响应,而前端缓存主要在请求处响应这两步...

yysue
39分钟前
0
0
00.编译OpenJDK-8u40的整个过程

前言 历经2天的折腾总算把OpenJDK给编译成功了,要说为啥搞这个,还得从面试说起,最近出去面试经常被问到JVM的相关东西,总感觉自己以前学的太浅薄,所以回来就打算深入学习,目标把《深入理...

凌晨一点
今天
4
0
python: 一些关于元组的碎碎念

初始化元组的时候,尤其是元组里面只有一个元素的时候,会出现一些很蛋疼的情况: def checkContentAndType(obj): print(obj) print(type(obj))if __name__=="__main__": tu...

Oh_really
昨天
6
2
jvm crash分析工具

介绍一款非常好用的jvm crash分析工具,当jvm挂掉时,会产生hs_err_pid.log。里面记录了jvm当时的运行状态以及错误信息,但是内容量比较庞大,不好分析。所以我们要借助工具来帮我们。 Cras...

xpbob
昨天
126
0
Qt编写自定义控件属性设计器

以前做.NET开发中,.NET直接就集成了属性设计器,VS不愧是宇宙第一IDE,你能够想到的都给你封装好了,用起来不要太爽!因为项目需要自从全面转Qt开发已经6年有余,在工业控制领域,有一些应用...

飞扬青云
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部