文档章节

Java中的Set集合类

谢思华
 谢思华
发布于 2015/06/10 12:11
字数 1350
阅读 1980
收藏 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();
}

}


© 著作权归作者所有

共有 人打赏支持
谢思华
粉丝 64
博文 210
码字总数 135083
作品 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
2018/07/03
0
0
[Java 并发编程] 集合框架之 同步容器类 & 并发容器类

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

seaicelin
2018/05/25
0
0
Java编程学习:集合框架详解

Java是一种可以撰写跨平台应用软件的面向对象的程序设计语言。Java 技术具有卓越的通用性、高效性、平台移植性和安全性,广泛应用于PC、数据中心、游戏控制台、科学超级计算机、移动电话和互...

Java小辰
2018/05/30
0
0
iReport 中创建JavaBeanDataSource,用java类提供数据源给iReport

iReport 中创建JavaBeanDataSource 用JavaBeanDataSource是为了调试制作的报表效果如何,所以要首先要让 iReport能找到class文件,为此要配置iReport的classpath. 步骤如下: 点击 工具 ----...

AblimitAbduxkur
2012/11/04
0
3
Java每天10道面试题,跟我走,offer有!(五)

41.Iterator、ListIterator 和 Enumeration的区别? 42.Java 中 Set 与 List 有什么不同? 43.arraylist 与 vector 的区别? 44.什么类实现了List接口? 这里推荐一下我的Java后端高级技术群:...

Java干货分享
2018/11/16
0
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周三乱弹 —— 风扇写着先生请自爱

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @蚂蚁哈哈哈 :分享陈奕迅的单曲《落花流水》 《落花流水》- 陈奕迅 手机党少年们想听歌,请使劲儿戳(这里) @车谷 :我发现每天上班都好困 ...

小小编辑
今天
242
6
centos7重置密码、单用户模式、救援模式、ls命令、chmod命令

在工作当中如果我们错误的配置了文件使服务器不能正常启动或者忘记密码不能登录系统,如何解决这些问题呢?重装系统是可以实现的,但是往往不能轻易重装系统的,下面用忘记密码作为例子讲解如...

李超小牛子
今天
4
0
Python如何开发桌面应用程序?Python基础教程,第十三讲,图形界面

当使用桌面应用程序的时候,有没有那么一瞬间,想学习一下桌面应用程序开发?行业内专业的桌面应用程序开发一般是C++,C#来做,Java开发的也有,但是比较少。本节课会介绍Python的GUI(图形用...

程序员补给栈
今天
12
0
kafka在的使用

一、基本概念 介绍 Kafka是一个分布式的、可分区的、可复制的消息系统。它提供了普通消息系统的功能,但具有自己独特的设计。 这个独特的设计是什么样的呢? 首先让我们看几个基本的消息系统...

狼王黄师傅
今天
3
0
Android JNI总结

0x01 JNI介绍 JNI是Java Native Interface的缩写,JNI不是Android专有的东西,它是从Java继承而来,但是在Android中,JNI的作用和重要性大大增强。 JNI在Android中起着连接Java和C/C++层的作...

天王盖地虎626
昨天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部