set学习笔记

Posted _图南

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了set学习笔记相关的知识,希望对你有一定的参考价值。

1 Set的介绍

set: 存储无序,不可重复的数据

    • Set接口是Collection的子接口,set接口没有提供额外的方法
    • Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个Set 集合中,则添加操作失败。
    • Set 判断两个对象是否相同不是使用==运算符,而是根据equals()

 

2 对与无序和不可重复的理解:

  无序性:存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值决定的。但是不等于随机性。

  不可重复性:保证添加的元素按照equals()判断时,不能返回true.即:相同的元素只能添加一个(TreeSet除外)。

        TreeSet是根据compareTo是否为0进行比较

 

3 Set接口实现类的对比

  ---Collection接口:

    ----set接口:存储无序,不可重复的数据

      ----HashSet:Set的主要实现类;线程不安全但是效率高;可以储存null值

        ----LinkedHashSet:是HashSet的子类。可以按照添加的顺序遍历

                  底层有前后指针,故对于频繁的遍历操作,LinkedHashSet效率是高于                               HashSet的

      ----TreeSet: 可以按照添加对象的指定属性(也就是说,属性的类型要相同),进行操作。

              底层是红黑树和HashMap一样

            

 

4 HashSet的特点:

不能保证元素的排列顺序
HashSet不是线程安全的
集合元素可以是null
底层也是数组,初始容量为16,当如果使用率超过0.75,(16*0.75=12)就会扩大容量为原来的2倍。(16扩容为32,依次为64,128…等)
HashSet 集合判断两个元素相等的标准:两个对象通过hashCode() 方法比较相等,并且两个对象的equals()方法返回值也相等。

5  添加元素过程

我们向HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,
* 此哈希值接着通过某种算法计算出在HashSet底层数组中的存放位置(即为:索引位置),判断
* 数组此位置上是否已经有元素:
* 如果此位置上没有其他元素,则元素a添加成功。 --->情况1
* 如果此位置上有其他元素b(或以链表形式存在的多个元素),则比较元素a与元素b的hash值:
* 如果hash值不相同,则元素a添加成功。--->情况2
* 如果hash值相同,进而需要调用元素a所在类的equals()方法:
* equals()返回true,元素a添加失败
* equals()返回false,则元素a添加成功。--->情况2
*
* 对于添加成功的情况2和情况3而言:元素a 与已经存在指定索引位置上数据以链表的方式存储。
* jdk 7 :元素a放到数组中,指向原来的元素。
* jdk 8 :原来的元素在数组中,指向元素a
* 总结:七上八下

 

6 HashCode()和equals()的重写

  为什么要重写HashCode和equals方法

  由于在创建对象时,Object类会随机生成一个哈希值。所以,即使对象的属性元素相同,在HashSet输出时,仍然输出两个对象,不符合不可重复性。故要重写HashCode和equals方法。

  具体操作idea有自动重写

 

7 LinkedHashSet

 LinkedHashSet 是 HashSet 的子类

 LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置, 但它同时使用双向链表维护元素的次序,这使得元素看起来是以插入 顺序保存的。

LinkedHashSet插入性能略低于 HashSet,但在迭代访问 Set 里的全 部元素时有很好的性能。

LinkedHashSet 不允许集合元素重复。

 

 内部原理图:

 

 

7 TreeSet

   

  • TreeSet底层使用红黑树结构存储数据
  • TreeSet可以确保集合元素处于排序状态。
  • TreeSet两种排序方法:自然排序和定制排序。默认情况下,TreeSet采用自然排序。定制排序是,在创建TreeSet的构造器是含参,并且使用Comparator方法。
  • 如果试图把一个对象添加到TreeSet时,则该对象的类必须实现Comparable 接口。
  • 自然排序:TreeSet会调用集合元素的compareTo(Object obj)方法来比较元素之间的大小关系,然后将集合元素按升序(默认情况)排列。
  • 对于TreeSet集合而言,它判断两个对象是否相等的唯一标准是:两个对象通过compareTo(Object obj)方法比较返回值。

 

Redis学习笔记-Set

package cn.com;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import redis.clients.jedis.Jedis;

/**
 * 集合的所有操作方法
 * 
 * */
public class Redis_Set {
	public static Jedis redis = new Jedis("localhost", 6379);// 连接redis
	
	public static void zadd(){
		Map<String,Double> map=new HashMap<String,Double>();
		redis.zadd("user",map);
		 
	}
	
	
	/**
	 * 将一个或多个  元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。
	 * */
	public static void sadd(){
		redis.flushDB();//清除数据
		redis.sadd("user", "a","b","c","d","e","f");
		Set<String> setList=redis.smembers("user");
		for(String s:setList){
			System.out.println(s);
		}
	}
	
	/**
	 * SCARD key
	 * 返回集合 key 的基数(集合中元素的数量)
	 * */
	public static void scard(){
		redis.flushDB();//清除数据
		redis.sadd("user", "a","b","c","d","e","f");
		Long number=redis.scard("user");
		System.out.println(number);
	}
	
	
	/**
	 * SDIFF key [key ...] 求差集
	 * 返回一个集合的全部成员,该集合是所有给定集合之间的差集。
	 * 不存在的 key 被视为空集。
	 * 相当月user减去user1 剩下的 user 元素
	 * */
	public static void sdiff(){
		redis.flushDB();//清除数据
		redis.sadd("user", "a","b","c","z");
		redis.sadd("user1", "a","c","d","f");
		
		Set<String> setList=redis.sdiff("user","user1");
		for(String s:setList){
			System.out.println(s);
		}
	}
	
	/**
	 * SDIFFSTORE destination key [key ...]求差集 将结果放入新的结合中
	 * 这个命令的作用和 SDIFF 类似,但它将结果保存到 destination 集合,而不是简单地返回结果集。
	 * 如果 destination 集合已经存在,则将其覆盖。
	 * destination 可以是 key 本身。
	 * N 是所有给定集合的成员数量之和.
	 * 例如:以下例子是 取出 user中在user1 不包含的元素 也就是(zzz)在user1 中不存在
	 * */
	public static void sdiffstore(){
		redis.flushDB();//清除数据
		redis.sadd("user", "a","b","c","zzzz");
		redis.sadd("user1", "a","b","c","d","e","f");
	 
		long size=redis.sdiffstore("newuser","user","user1");
		System.out.println("size:"+size);
		Set<String> setList=redis.smembers("newuser");
		for(String s:setList){
			System.out.println(s);
		}
	}
	
	/**
	 *  SINTER key [key ...] 求交集
	 * 返回一个集合的全部成员,该集合是所有给定集合的交集。
	 * 不存在的 key 被视为空集。
	 * 当给定集合当中有一个空集时,结果也为空集(根据集合运算定律)。
	 * */
	public static void sinter(){
		redis.flushDB();//清除数据
		redis.sadd("user", "a","b","c","zzzz");
		redis.sadd("user1", "a","b","c","d","e","f");
		Set<String> setList=redis.sinter("user","user1");
		for(String s:setList){
			System.out.println(s);
		}
	}
	
	/**
	 *  SINTER key [key ...] 求交集 跟sinter区别在于是将差集的结果集放入新的数组中 如下的:newuser
	 * 返回一个集合的全部成员,该集合是所有给定集合的交集。
	 * 不存在的 key 被视为空集。
	 * 当给定集合当中有一个空集时,结果也为空集(根据集合运算定律)。
	 * */
	public static void sinterstore(){
		redis.flushDB();//清除数据
		redis.sadd("user", "a","b","c","zzzz");
		redis.sadd("user1", "a","b","c","d","e","f");
		long size=redis.sinterstore("newuser","user","user1");
		System.out.println("交集的大小:"+size);
		
		Set<String> setList=redis.smembers("newuser");
		for(String s:setList){
			System.out.println(s);
		}
	}
	
	/**
	 * SUNION key [key ...]
	 * 返回一个集合的全部成员,该集合是所有给定集合的并集。
	 * 不存在的 key 被视为空集。
	 * */
	public static void sunion(){
		redis.flushDB();//清除数据
		redis.sadd("user", "a","b","c","zzzz");
		redis.sadd("user1", "a","b","c","d","e","f");
		Set<String> setList=redis.sunion("user","user1");
	
		for(String s:setList){
			System.out.println(s);
		}
	}
	
	/**
	 * SUNION key [key ...]  将两个集合的并集放入新的结合中 newuser
	 * 返回一个集合的全部成员,该集合是所有给定集合的并集。
	 * 不存在的 key 被视为空集。
	 * */
	public static void sunionstore(){
		redis.flushDB();//清除数据
		redis.sadd("user", "a","b","c","zzzz");
		redis.sadd("user1", "a","b","c","d","e","f");
		long l=redis.sunionstore("newuser","user","user1");
		Set<String> setList=redis.smembers("newuser");
		for(String s:setList){
			System.out.println(s);
		}
	}
	
	
	/**
	 * SISMEMBER key member
	 *判断 member 元素是否集合 key 的成员。
	 * */
	public static void sismember(){
		redis.flushDB();//清除数据
		redis.sadd("user", "a","b","c","zzzz");
		 
		boolean b=redis.sismember("user", "a");
		boolean b1=redis.sismember("user", "不存在哦");
		System.out.println("返回一个 true 跟 false");
		System.out.println(b);
		System.out.println(b1);
	}
	
	/**
	 * 获取集合对象
	 * */
	public static void smembers(){
		redis.flushDB();//清除数据
		redis.sadd("user", "a","b","c","d","e","f");
		Set<String> setList=redis.smembers("user");
		for(String s:setList){
			System.out.println(s);
		}
	}
	
	
	/**
	 * SMOVE source destination member
	 * SMOVE 是原子性操作。
	 * @param srckey 源集合key
	 * @param dstkey 目标集合key
	 * @param member 要移动的元素
	 * 将源集合中的 元素member 移动到目标集合中
	 * 返回值:
 	 * 如果 member 元素被成功移除,返回 1 。
     * 如果 member 元素不是 source 集合的成员,并且没有任何操作对 destination 集合执行,那么返回 0 。
	 */
	public static void smove(){
		redis.flushDB();//清除数据
		redis.sadd("user", "a","b","c","zzzz");
		redis.sadd("user1",  "d","e","f");
		redis.smove("user", "user1", "zzzz"); 
		System.out.println("======user剩下的元素应该是 a,b,c======");
		Set<String> setList=redis.smembers("user");
		for(String s:setList){
			System.out.println(s);
		}
		
		System.out.println("======user 1的元素应该是 d,e,f,zzz======");
		Set<String> setList1=redis.smembers("user1");
		for(String s:setList1){
			System.out.println(s);
		}
	}
	
	/**
	 * SPOP key
	 * 移除并返回集合中的一个随机元素。
	 * 如果只想获取一个随机元素,但不想该元素从集合中被移除的话,可以使用 SRANDMEMBER 命令。
	 * */
	public static void spop(){
		redis.flushDB();//清除数据
		redis.sadd("user", "1","2","3","4","5","6","7");
		String s=redis.spop("user");
		System.out.println("随机弹出并移除的元素:"+s);
		Set<String> setList=redis.smembers("user");
		for(String str:setList){
			System.out.println(str);
		}
	}
	
	
	/**
	 * 如果命令执行时,只提供了 key 参数,那么返回集合中的一个随机元素。
	 * */
	public static void srandmember(){
		redis.flushDB();//清除数据
		redis.sadd("user", "1","2","3","4","5","6","7");
		String s=redis.srandmember("user");
		System.out.println("随机弹出不删除的元素:"+s);
		 
		Set<String> setList=redis.smembers("user");
		for(String str:setList){
			System.out.println(str);
		}
	}
	
	/**
	 * SREM key member [member ...]
	 * 移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略。
	 * 当 key 不是集合类型,返回一个错误。
	 * */
	public static void srem(){
		redis.flushDB();//清除数据
		redis.sadd("user", "1","2","3","4","5","6","7");
		redis.srem("user", "1","3","5");//删除1,3,5
		Set<String> setList=redis.smembers("user");
		for(String str:setList){
			System.out.println(str);
		}
	}
	
	
	public static void main(String [] args){
		sunionstore();
	}
}

  

以上是关于set学习笔记的主要内容,如果未能解决你的问题,请参考以下文章

Mybatis 学习笔记总结

Mybatis学习笔记:动态SQL

DOM探索之基础详解——学习笔记

Swift学习笔记之---Set集合类型

Swift学习笔记之---Set集合类型

Swift学习笔记之---Set集合类型