Java中的Set集合类
Java中的Set集合类
谢思华 发表于3年前
Java中的Set集合类
  • 发表于 3年前
  • 阅读 774
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

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();
}

}


标签: Set集合类
共有 人打赏支持
粉丝 54
博文 136
码字总数 112046
×
谢思华
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: