精华内容
下载资源
问答
  • set保证数据唯一
    千次阅读
    2021-03-15 02:27:12

    在说明问题之前我们先来看一段经常性使用的代码

    function fun(){

    开启事务

    try{

    var count = find();

    if(count<1){

    insert();

    }

    提交事务

    }catch(e){

    事务回滚

    }

    }

    在以上代码中我们在一个事务中,先查询是否存在我们要插入的数据,如果不存在则插入数据,存在则不插入数据。我们很当然的认为这很完美,我在代码中进行了唯一性验证,数据表中肯定不会存在相同的数据记录。在单机应用中或不存在高并发情况确实能够保证我们数据的唯一性。在分布式高并发系统中,该写法是无法保证数据表数据的唯一性。

    在单应用系统中为保证数据表中数据主键的唯一性一般我们使用的方法有:

    1、数据表增加唯一性约束(单一数据库最简单方式)

    增加数据表唯一性约束是最简单的方式,只需要在我们需要的字段中增加唯一约束,当插入相同数据时,数据库会验证数据唯一,当存在相同主键时,数据库会抛出异常信息。

    2、使用insert select where not exists 方式

    数据表插入语句使用insert select 方式,如在temp_table中增加名称为name1的数据记录,名字列唯一

    insert into temp_table(name) select 'name1' from dual where not exists(select 1 from temp_table where name ='name1');

    3、使用同步(synchronous)

    程序保存代码块中增加并发同步控制,该方法可以防止并发执行,单程序效率会降低。

    更新语句写法

    for update显示加锁

    把udpate语句写在前边,先把数量-1,之后select出库存如果>-1就commit,否则rollback。

    update products set quantity = quantity-1 WHERE id=3;

    select quantity from products WHERE id=3 for update;

    update语句在更新的同时加上一个条件

    quantity = select quantity from products WHERE id=3;

    update products set quantity = ($quantity-1) WHERE id=3 and queantity = $quantity;

    更多相关内容
  • Set是如何保证里面的元素唯一

    千次阅读 2016-10-14 23:31:18
    set保证里面元素的唯一性其实是靠两个方法,一是equals()和hashCode()方法 往set里面添加数据的时候一般会有隐式的操作 先是判断set集合中是否有与新添加数据的hashcode值一致的数据, 如果有,那么将再进行第二步调...

    set保证里面元素的唯一性其实是靠两个方法,一是equals()和hashCode()方法

    往set里面添加数据的时候一般会有隐式的操作

    先是判断set集合中是否有与新添加数据的hashcode值一致的数据,

    如果有,那么将再进行第二步调用equals方法再进行一次判断,

    假如集合中没有与新添加数据hashcode值一致的数据,那么将不调用eqauls方法。


    那么就有一个疑问了,如果往里面添加对象呢?

    下面是一段往set中添加对象的代码

    import java.util.*;
    class Person
    {
    	private String name;
    	private int age;
    	Person(String name,int age){
    		this.name = name;
    		this.age = age;
    	}
    	
    }
    class HashCodeDemo 
    {
    	public static void main(String[] args) 
    	{
    		Set<Person> s = new HashSet<Person>();
    
    		Person p = new Person("sdchen",20);
    		Person p1 = new Person("sdchen",20);
    		
    		System.out.println("p.hashCode=" + p.hashCode());
    		System.out.println("p1.hashCode=" + p1.hashCode());
    
    		s.add(p);
    		s.add(p1);
    		System.out.println(s.size());
    		//System.out.println("p.contains(p1)=" + s.contains(p1));
    	}
    }
    
    以下是执行后的效果图

    我们可以看到两个对象的hashcode值不一样而且添加后的set集合的大小为2,那么毫无疑问虽然两个对象的值是一样的但还是添加进去了,这不符合我们的要求,

    这就验证了上面的理论了,hashcode值不同底层就不会调用equals方法判断,直接将两个对象添加进去了,楼主刚开始是想复写一下equals方法就行了,但是经

    过验证后是不行了,这也用到了上面的理论,两个对象的hashcode值不一样是不会调用eqauls方法的,那么我们就只重写hashcode()方法呢?最后的结果也是不行的,

    下面上传一下只重写hashcede()方法的代码

    import java.util.*;
    class Person
    {
    	private String name;
    	private int age;
    	Person(String name,int age){
    		this.name = name;
    		this.age = age;
    	}
    	public int hashCode(){
    		return this.name.hashCode() + age * 39;
    	}
    	
    }
    class HashCodeDemo 
    {
    	public static void main(String[] args) 
    	{
    		Set<Person> s = new HashSet<Person>();
    
    		Person p = new Person("sdchen",20);
    		Person p1 = new Person("sdchen",20);
    		
    		System.out.println("p.hashCode=" + p.hashCode());
    		System.out.println("p1.hashCode=" + p1.hashCode());
    
    		s.add(p);
    		s.add(p1);
    		System.out.println(s.size());
    		//System.out.println("p.contains(p1)=" + s.contains(p1));
    	}
    }
    
    下面是运行效果图



    我们清楚的看见两个对象的hashcode值是一样的,但是添加后的set集合的大小还是2,那么我们只重写hashcode()方法是没有作用的,

    那么下面我们就上传一下重写equals()方法和重写hashcode()方法的代码

    import java.util.*;
    class Person
    {
    	private String name;
    	private int age;
    	Person(String name,int age){
    		this.name = name;
    		this.age = age;
    	}
    	public int hashCode(){
    		return this.name.hashCode() + age * 39;
    	}
    	public boolean equals(Object o){
    
    		if(!(o instanceof Person))
    			return false;
    
    		System.out.println("执行了equals方法");
    		Person p = (Person)o;
    		return this.name == p.name && this.age == p.age;
    	}
    	
    }
    class HashCodeDemo 
    {
    	public static void main(String[] args) 
    	{
    		Set<Person> s = new HashSet<Person>();
    
    		Person p = new Person("sdchen",20);
    		Person p1 = new Person("sdchen",20);
    		
    		System.out.println("p.hashCode=" + p.hashCode());
    		System.out.println("p1.hashCode=" + p1.hashCode());
    
    		s.add(p);
    		s.add(p1);
    		System.out.println(s.size());
    		//System.out.println("p.contains(p1)=" + s.contains(p1));
    	}
    }
    我特意在equals方法中随便打印了一下,验证了hashcode值一样的时候确实是调用了hashcode方法(),下面是执行后的截图



    我们清楚的看见了确实调用了equals方法 而且最后打印set的大小是1,那么这就符合了我们的需求了


    新手,有什么不足之处欢迎大家指出,定会虚心学习


    展开全文
  • 数据结构之Java实现底层Set

    万次阅读 2018-09-22 10:05:05
    Set也是一种重要数据结构,其特点为不允许出现重复元素,不保证集合中的元素顺序,可以有元素为null但只允许出现一次。首先定义了一个Set接口,根据前面几篇文章实现的链表和二分搜索树实现Set数据结构,下面是实现...

    Set也是一种重要数据结构,其特点为不允许出现重复元素,不保证集合中的元素顺序,可以有元素为null但只允许出现一次。首先定义了一个Set接口,根据前面几篇文章实现的链表和二分搜索树实现Set数据结构,下面是实现过程

    Set接口

    public interface Set<E> {
     void add(E e);   //添加一个元素
     void remove(E e);  //删除一个元素
     boolean contain(E e);//判断是否包含元素
     int getSize();   //获取集合大小
     boolean isEmpty();  //判断是否为空
    }
    1.链表实现Set,可以保证元素的顺序,主要注意避免重复元素

    public class LinkedListSet<E> implements Set<E> {

        private LinkedList<E> list;

        public LinkedListSet(){
            list = new LinkedList<>();
        }

        @Override
        public int getSize(){
            return list.getSize();
        }

        @Override
        public boolean isEmpty(){
            return list.isEmpty();
        }

        @Override
        public void add(E e){
            if(!list.contain(e))    //避免重复元素
                list.addFirst(e);
        }

        @Override
        public boolean contain(E e){
            return list.contain(e);
        }

        @Override
        public void remove(E e){
           list.removeElement(e);
        }
    }

    2.二分搜索树实现Set,可以保证元素的唯一性

    public class BSTSet<E extends Comparable<E>> implements Set<E>{
     private BST<E> bst;
     
     public BSTSet() {
      bst = new BST<>();
     }
     
     @Override
     public void add(E e) {
      bst.add(e);
     }

     @Override
     public void remove(E e) {
      bst.remove(e);
     }

     @Override
     public boolean contain(E e) {

      return bst.contain(e);
     }

     @Override
     public int getSize() {

      return bst.size();
     }

     @Override
     public boolean isEmpty() {

      return bst.isEmpty();
     }
    }

    由于前面自己实现了链表(https://blog.csdn.net/zhangjun62/article/details/82758823)和二分搜索树(https://blog.csdn.net/zhangjun62/article/details/82766695)这两个数据结构,所以实现Set集合比较容易.对于LinkedListSet 增、查、改时间复杂度都为O(n), 对于BSTSet 增、查、改时间复杂度为O(h),其中h为树的高度,二叉树元素最多的情况是满二叉树, 满二叉树每一层元素个数为2 ^( h - 1)(h = 0, 1, 2,..., h), 根据等比数列求和可知总的元素个数n = 2 ^ h - 1, 所以h为以2底n + 1的对数,所以BST增、查、改时间复杂度O(h) = O(log n), 优于LinkedListSet.写了一个测试用例,比较两者耗时操作,下面是比较读取文件文本内容并统计词汇量的耗时测试程序。首先实现读取文件的工具类

    public class FileOperation {

        public static boolean readFile(String filename, ArrayList<String> words){

            if (filename == null || words == null){
                System.out.println("filename is null or words is null");
                return false;
            }

            Scanner scanner;

            try {
                File file = new File(filename);
                if(file.exists()){
                    FileInputStream fis = new FileInputStream(file);
                    scanner = new Scanner(new BufferedInputStream(fis), "UTF-8");
                    scanner.useLocale(Locale.ENGLISH);
                }
                else
                    return false;
            }
            catch(IOException ioe){
                System.out.println("Cannot open " + filename);
                return false;
            }

            if (scanner.hasNextLine()) {

                String contents = scanner.useDelimiter("\\A").next();

                int start = firstCharacterIndex(contents, 0);
                for (int i = start + 1; i <= contents.length(); )
                    if (i == contents.length() || !Character.isLetter(contents.charAt(i))) {
                        String word = contents.substring(start, i).toLowerCase();
                        words.add(word);
                        start = firstCharacterIndex(contents, i);
                        i = start + 1;
                    } else
                        i++;
            }

            return true;
        }

        private static int firstCharacterIndex(String s, int start){

            for( int i = start ; i < s.length() ; i ++ )
                if( Character.isLetter(s.charAt(i)) )
                    return i;
            return s.length();
        }
    }

    下面是测试程序,文本是傲慢与偏见英文版

    public class Main {

     private static double testSet(Set<String> set, String filename) {

      long startTime = System.nanoTime();

      System.out.println(filename);
      ArrayList<String> words = new ArrayList<>();
      if (FileOperation.readFile(filename, words)) {
       System.out.println("Total words: " + words.size());

       for (String word : words)
        set.add(word);
       System.out.println("Total different words: " + set.getSize());
      }
      long endTime = System.nanoTime();

      return (endTime - startTime) / 1000000000.0;
     }

     public static void main(String[] args) {

      String filename = "pride-and-prejudice.txt";

      BSTSet<String> bstSet = new BSTSet<>();
      double time1 = testSet(bstSet, filename);
      System.out.println("BST Set: " + time1 + " s");

      System.out.println();

      LinkedListSet<String> linkedListSet = new LinkedListSet<>();
      double time2 = testSet(linkedListSet, filename);
      System.out.println("Linked List Set: " + time2 + " s");

     }

    }

    每个人电脑配置和性能不一样,时间会不同,但两者差异还是会有体现的,以下是测试结果

    这个结果表明二分搜索树实现的Set的时间复杂度确实优于链表实现的Set,以上整个过程就实现Set基本功能。

     

     

    展开全文
  • C++ map,set内部数据结构

    千次阅读 2017-09-22 17:21:02
    1)Set是一种关联容器,它用于存储数据,并且能从一个数据集合中取出数据。它的每个元素的值必须唯一,而且系统会根据该值来自动将数据排序。每个元素的值不能直接被改变。【重点】内部结构采用红黑树的平衡二叉树。...

    1)Set是一种关联容器,它用于存储数据,并且能从一个数据集合中取出数据。它的每个元素的值必须唯一,而且系统会根据该值来自动将数据排序。每个元素的值不能直接被改变。【重点】内部结构采用红黑树的平衡二叉树。multiset 跟set 类似,唯一的区别是允许键值重复!!!

    如: 为何map和set的插入删除效率比用其他序列容器高?

           为何每次insert之后,以前保存的iterator不会失效?

           为何map和set不能像vector一样有个reserve函数来预分配数据?

            当数据元素增多时(10000到20000个比较),map和set的插入和搜索速度变化如何?

    或许有得人能回答出来大概原因,但要彻底明白,还需要了解STL的底层数据结构。 C++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构算法和大量常用数据结构操作。vector封装数组,list封装了链表,map和 set封装了二叉树,在封装这些数据结构的时候,STL按照程序员的使用习惯,以成员函数方式提供的常用操作,如:插入、排序、删除、查找等。让用户在 STL使用过程中,并不会感到陌生。 C++ STL中标准关联容器set, multiset, map, multimap内部采用的就是一种非常高效的平衡检索二叉树:红黑树,也成为RB树(Red-Black Tree)。RB树的统计性能要好于一般的平衡二叉树(有些书籍根据作者姓名,Adelson-Velskii和Landis,将其称为AVL-树),所以被STL选择作为了关联容器的内部结构。本文并不会介绍详细AVL树和RB树的实现以及他们的优劣,关于RB树的详细实现参看红黑树: 理论与实现(理论篇)。本文针对开始提出的几个问题的回答,来向大家简单介绍map和set的底层数据结构。

    为何map和set的插入删除效率比用其他序列容器高? 大部分人说,很简单,因为对于关联容器来说,不需要做内存拷贝和内存移动。说对了,确实如此。map和set容器内所有元素都是以节点的方式来存储,其节点结构和链表差不多,指向父节点和子节点。

    结构图可能如下:

         A

        /  /

      B    C

     / /   / /

    D  E F  G

    因此插入的时候只需要稍做变换,把节点的指针指向新的节点就可以了。删除的时候类似,稍做变换后把指向删除节点的指针指向其他节点就OK了。这里的一切操作就是指针换来换去,和内存移动没有关系。 为何每次insert之后,以前保存的iterator不会失效? 看见了上面答案的解释,你应该已经可以很容易解释这个问题。iterator这里就相当于指向节点的指针,内存没有变,指向内存的指针怎么会失效呢(当然 被删除的那个元素本身已经失效了)。相对于vector来说,每一次删除和插入,指针都有可能失效,调用push_back在尾部插入也是如此。因为为了 保证内部数据的连续存放,iterator指向的那块内存在删除和插入过程中可能已经被其他内存覆盖或者内存已经被释放了。即使时push_back的时 候,容器内部空间可能不够,需要一块新的更大的内存,只有把以前的内存释放,申请新的更大的内存,复制已有的数据元素到新的内存,最后把需要插入的元素放 到最后,那么以前的内存指针自然就不可用了。特别时在和find等算法在一起使用的时候,牢记这个原则:不要使用过期的iterator。 为何map和set不能像vector一样有个reserve函数来预分配数据? 我以前也这么问,究其原理来说时,引起它的原因在于在map和set内部存储的已经不是元素本身了,而是包含元素的节点。也就是说map内部使用的Alloc并不是map声明的时候从参数中传入的Alloc。例如: map, Alloc > intmap; 这时候在intmap中使用的allocator并不是Alloc, 而是通过了转换的Alloc,具体转换的方法时在内部通过Alloc::rebind重新定义了新的节点分配器,详细的实现参看彻底学习STL中的Allocator。其实你就记住一点,在map和set内面的分配器已经发生了变化,reserve方法你就不要奢望了。 当数据元素增多时(10000和20000个比较),map和set的插入和搜索速度变化如何? 如果你知道log2的关系你应该就彻底了解这个答案在map和set中查找是使用二分查找,也就是说,如果有16个元素,最多需要比较4次就能找到结 果,有32个元素,最多比较5次。那么有10000个呢?最多比较的次数为log10000,最多为14次,如果是20000个元素呢?最多不过15次。 看见了吧,当数据量增大一倍的时候,搜索次数只不过多了1次,多了1/14的搜索时间而已。你明白这个道理后,就可以安心往里面放入元素了。 最后,对于map和set Winter还要提的就是它们和一个c语言包装库的效率比较。在许多unix和linux平台下,都有一个库叫isc,里面就提供类似于以下声明的函数: void tree_init(void **tree); void *tree_srch(void **tree, int (*compare)(), void *data); void tree_add(void **tree, int (*compare)(), void *data, void (*del_uar)()); int tree_delete(void **tree, int (*compare)(), void *data,void (*del_uar)()); int tree_trav(void **tree, int (*trav_uar)()); void tree_mung(void **tree, void (*del_uar)()); 许多人认为直接使用这些函数会比STL map速度快,因为STL map中使用了许多模板什么的。其实不然,它们的区别并不在于算法,而在于内存碎片。如果直接使用这些函数,你需要自己去new一些节点,当节点特别多, 而且进行频繁的删除和插入的时候,内存碎片就会存在,而STL采用自己的Allocator分配内存,以内存池的方式来管理这些内存,会大大减少内存碎 片,从而会提升系统的整体性能。Winter在自己的系统中做过测试,把以前所有直接用isc函数的代码替换成map,程序速度基本一致。当时间运行很长 时间后(例如后台服务程序),map的优势就会体现出来。从另外一个方面讲,使用map会大大降低你的编码难度,同时增加程序的可读性。何乐而不为?


    /*
    
    set/multiset会根据待定的排序准则,自动将元素排序。两者不同在于前者不允许元素重复,而后者允许。
    
    1) 不能直接改变元素值,因为那样会打乱原本正确的顺序,要改变元素值必须先删除旧元素,则插入新元素
    
    2) 不提供直接存取元素的任何操作函数,只能通过迭代器进行间接存取,而且从迭代器角度来看,元素值是常数
    
    3) 元素比较动作只能用于型别相同的容器(即元素和排序准则必须相同)
    
    set模板原型://Key为元素(键值)类型
    
    template <class Key, class Compare=less<Key>, class Alloc=STL_DEFAULT_ALLOCATOR(Key) >
    
    从原型可以看出,可以看出比较函数对象及内存分配器采用的是默认参数,因此如果未指定,它们将采用系统默认方式,
    
    另外,利用原型,可以有效地辅助分析创建对象的几种方式
    
    */
    
    #include <iostream>
    
    #include <string>
    
    #include <set>
    
     
    
    using namespace std;
    
     
    
    struct strLess
    
    {
    
       bool operator() (const char *s1, const char *s2) const
    
       {
    
        return strcmp(s1, s2) < 0;
    
       }
    
    };
    
     
    
    void printSet(set<int> s)
    
    {
    
    copy(s.begin(), s.end(), ostream_iterator<int>(cout, ", ") );
    
     
    
    // set<int>::iterator iter;
    
    // for (iter = s.begin(); iter != s.end(); iter++)
    
    //    //cout<<"set["<<iter-s.begin()<<"]="<<*iter<<", "; //Error
    
    //    cout<<*iter<<", ";
    
    cout<<endl;
    
    }
    
     
    
    void main()
    
    {
    
    //创建set对象,共5种方式,提示如果比较函数对象及内存分配器未出现,即表示采用的是系统默认方式
    
    //创建空的set对象,元素类型为int,
    
    set<int> s1;
    
    //创建空的set对象,元素类型char*,比较函数对象(即排序准则)为自定义strLess
    
    set<const char*, strLess> s2( strLess);
    
    //利用set对象s1,拷贝生成set对象s2
    
    set<int> s3(s1);
    
    //用迭代区间[&first, &last)所指的元素,创建一个set对象
    
    int iArray[] = {13, 32, 19};
    
    set<int> s4(iArray, iArray + 3);
    
    //用迭代区间[&first, &last)所指的元素,及比较函数对象strLess,创建一个set对象
    
    const char* szArray[] = {"hello", "dog", "bird" };
    
    set<const char*, strLess> s5(szArray, szArray + 3, strLess() );
    
     
    
    //元素插入:
    
    //1,插入value,返回pair配对对象,可以根据.second判断是否插入成功。(提示:value不能与set容器内元素重复)
    
    //pair<iterator, bool> insert(value)
    
    //2,在pos位置之前插入value,返回新元素位置,但不一定能插入成功
    
    //iterator insert(&pos, value)
    
    //3,将迭代区间[&first, &last)内所有的元素,插入到set容器
    
    //void insert[&first, &last)
    
    cout<<"s1.insert() : "<<endl;
    
    for (int i = 0; i <5 ; i++)
    
        s1.insert(i*10);
    
    printSet(s1);
    
     
    
    cout<<"s1.insert(20).second = "<<endl;;
    
    if (s1.insert(20).second)
    
        cout<<"Insert OK!"<<endl;
    
    else
    
        cout<<"Insert Failed!"<<endl;
    
     
    
    cout<<"s1.insert(50).second = "<<endl;
    
    if (s1.insert(50).second)
    
    {cout<<"Insert OK!"<<endl; printSet(s1);}
    
    else
    
        cout<<"Insert Failed!"<<endl;
    
     
    
    cout<<"pair<set<int>::iterator::iterator, bool> p;\np = s1.insert(60);\nif (p.second):"<<endl;
    
    pair<set<int>::iterator::iterator, bool> p;
    
    p = s1.insert(60);
    
    if (p.second)
    
    {cout<<"Insert OK!"<<endl; printSet(s1);}
    
    else
    
       cout<<"Insert Failed!"<<endl;
    
     
    
    //元素删除
    
    //1,size_type erase(value) 移除set容器内元素值为value的所有元素,返回移除的元素个数
    
    //2,void erase(&pos) 移除pos位置上的元素,无返回值
    
    //3,void erase(&first, &last) 移除迭代区间[&first, &last)内的元素,无返回值
    
    //4,void clear(), 移除set容器内所有元素
    
     
    
    cout<<"\ns1.erase(70) = "<<endl;
    
    s1.erase(70);
    
    printSet(s1);
    
    cout<<"s1.erase(60) = "<<endl;
    
    s1.erase(60);
    
    printSet(s1);
    
     
    
    cout<<"set<int>::iterator iter = s1.begin();\ns1.erase(iter) = "<<endl;
    
    set<int>::iterator iter = s1.begin();
    
    s1.erase(iter);
    
    printSet(s1);
    
     
    
    //元素查找
    
    //count(value)返回set对象内元素值为value的元素个数
    
    //iterator find(value)返回value所在位置,找不到value将返回end()
    
    //lower_bound(value),upper_bound(value), equal_range(value) 略
    
    cout<<"\ns1.count(10) = "<<s1.count(10)<<", s1.count(80) = "<<s1.count(80)<<endl;
    
    cout<<"s1.find(10) : ";
    
    if (s1.find(10) != s1.end())
    
        cout<<"OK!"<<endl;
    
    else
    
        cout<<"not found!"<<endl;
    
     
    
    cout<<"s1.find(80) : ";
    
    if (s1.find(80) != s1.end())
    
        cout<<"OK!"<<endl;
    
    else
    
        cout<<"not found!"<<endl;
    
     
    
    //其它常用函数
    
    cout<<"\ns1.empty()="<<s1.empty()<<", s1.size()="<<s1.size()<<endl;
    
    set<int> s9;
    
    s9.insert(100);
    
    cout<<"s1.swap(s9) :"<<endl;
    
    s1.swap(s9);
    
    cout<<"s1: "<<endl;
    
    printSet(s1);
    
    cout<<"s9: "<<endl;
    
    printSet(s9);
    
    //lower_bound,upper_bound,equal_range(略)
    
    }
    
     
    
     
    
    ///i测试结果/
    
    s1.insert() :
    
    0, 10, 20, 30, 40,
    
    s1.insert(20).second =
    
    Insert Failed!
    
    s1.insert(50).second =
    
    Insert OK!
    
    0, 10, 20, 30, 40, 50,
    
    pair<set<int>::iterator::iterator, bool> p;
    
    p = s1.insert(60);
    
    if (p.second):
    
    Insert OK!
    
    0, 10, 20, 30, 40, 50, 60,
    
     
    
    s1.erase(70) =
    
    0, 10, 20, 30, 40, 50, 60,
    
    s1.erase(60) =
    
    0, 10, 20, 30, 40, 50,
    
    set<int>::iterator iter = s1.begin();
    
    s1.erase(iter) =
    
    10, 20, 30, 40, 50,
    
     
    
    s1.count(10) = 1, s1.count(80) = 0
    
    s1.find(10) : OK!
    
    s1.find(80) : not found!
    
     
    
    s1.empty()=0, s1.size()=5
    
    s1.swap(s9) :
    
    s1:
    
    100,
    
    s9:
    
    10, 20, 30, 40, 50,


    展开全文
  • ES6 Set和Map数据结构(可转为数组)

    千次阅读 2018-11-07 21:58:02
    ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。(不包括空对象) Set 本身是一个构造函数,用来生成 Set 数据结构。 const s = new Set(); [2, 3, 5, 4, 5, 2, 2].forEach(x =&...
  • 接下来,我们一起学习Collection中的常用几个子类(List集合、Set集合)。1.1 List接口介绍查阅API,看List的介绍。有序的 collection(也称为序列)。此接口的用户可以对列表中每个元素的插入位置进行精确地控制。...
  • HashSet如何保证元素唯一性?

    千次阅读 2017-02-24 14:32:18
    Collection中的Set分为HashSet和TreeSet Set中的元素是无序的,即存入和取出的顺序...那么HashSet是如何保证元素唯一性的呢?首先我们先直观地看看哈希值的样子 class Demo{ }public class HashSetTest { public stat
  • set数据

    千次阅读 2017-06-19 14:04:06
    ,所以必须重写hashCode方法,才能保证两个不同的对象具有相同的hashCode, 同时也需要两个不同对象比较equals方法会返回true ===================================treeset===============================...
  • Set集合是如何保证元素不重复

    千次阅读 2019-12-14 17:10:06
    这里写自定义目录标题Set集合是如何保证元素不可重复总结 Set集合是如何保证元素不可重复 在使用集合的时候,会经常用到Set集合,Set集合的特点如下: 1,元素无序 2,元素不可重复 那么Set集合底层是如何保证元素...
  • 【Redis学习】:set数据类型详解

    千次阅读 2017-05-29 22:58:44
    set数据结构 常用命令 添加/删除元素 sadd key values[value1 value2 ...] 向set中添加数据,如果该key的值已有不会重复添加。 srem key members[member1 member2 ...] 删除set中指定的成员 获得...
  • 对于数据库来说,关系型数据库对于保证数据完整性和一致性方面表现是最好的! 数据的完整性 完整性分类 具体描述 如何保证 实体完整性 每个实体都是独一无二的 主键 / 唯一索引(唯一约束) 参照完整性...
  • STL中map、set数据结构及底层实现

    千次阅读 2018-12-15 17:19:58
    本文分析了STL的map和set vector(向量)——STL中标准而安全的数组。只能在vector 的“前面”增加数据。 deque(双端队列double-ended queue)——在功能上和vector相似,但是可以在前后两端向其中添加数据。  ...
  • List、Set数据结构、Collections

    千次阅读 2018-08-14 16:15:29
    哈希表:保证存储元素的唯一性; B).Map(双列集合): 02.第一章:List集合_List接口中的常用方法: 1).增: public void add(int index, E ele) : 将元素ele添加到index位置。 2).删: public E remove...
  • 高并发下如何保证数据的一致性

    千次阅读 2021-03-14 14:59:56
    写redis数据时,同时产生一条业务相关联的日志数据。单独开个任务或者消息队列来对日志数据进行读取,获取里面的对数据库的操作。然后进行写数据库。5.因为redis支持事务,所有写操作可以通过lua脚本来支持...
  • 1 白话hash_set/unordered_set  这一章节,我们来了解两个新的结构体hash_set和unorderd_set。...后面我们还会介绍到hash_map与unordered_map两种数据结构,这就好比是set与map的区别了,后面我们再说。
  • Java 集合List、Set、Map知识结构大全详解

    千次阅读 多人点赞 2019-07-17 16:37:51
    目录 概述 一、Collection 接口 (1)List列表 —— 有序、值可重复 (2)Set 集 —— 值不可重复 二、Map 接口 (1)HashMap —— 无序 1、取模法 2、Hash碰撞冲突 ...三、List、Set、Map的值能否...
  • 10. Redis 五种数据类型-集合Set

    万次阅读 2019-08-27 16:09:01
    Redis 中的Set 数据结构存储的是一组无序且唯一的元素集合. 1. 常用命令 操作命令 描述 返回值 smembers $key 获取set中所有元素 sadd $key member[member [member[member…] 向set...
  • redis(六)之redis基础数据结构set和zset

    千次阅读 2019-03-19 16:14:37
    set Redis的集合相当于Java语言里面的HashSet,它内部键值对是...set结构可以用来存储某活动中中奖的用户ID,因为有去重功能,可以保证同一个用户不会中奖两次。 简单命令: 检验某个值是否存在 zset zset类似于Jav...
  • 高并发下如何保证数据的一致性常用方法(JMM篇)

    万次阅读 多人点赞 2020-03-12 15:43:14
    最近复习了一下JMM的相关内容,总结了下如何处理多线程间访问共享变量带来的数据不一致问题的解决方案及原理说明,主要使用到的方法有synchronized关键字、volatile关键字、ReentrantLock同步锁、java.util....
  • 集合的底层数据结构原理决定了集合的一些特性,在这里对这几种数据结构特点简答介绍下,这几种数据结构也是最常见数据结构。
  • 定义了一个集合,存放了自定的数据,但是发现数据多的时候,只能插入两条数据;经过调研发现是自定义类型的小于操作符重载函数问题:之前判断的条件是,如果两个路径长度不相等,则表示该类型不一样;之后的条件是:...
  • 新增/修改数据时校验字段唯一

    千次阅读 2020-07-20 10:46:36
    新增/修改数据时校验字段唯一性 假定有实体类RuleAssign.java,对应如下表: id type rule 1 a 1001 2 b 1002 3 c 1003 一、单字段校验 前端传过来一批数据List<ruleAssign> datas,需要对rule...
  • 无序集合(set数据类型

    千次阅读 2016-02-26 11:02:34
     在Redis中,我们可以将Set类型看作为没有排序的字符集合,和List类型一样,我们也可以在该类型的数据值上执行添加、删除或判断某一元素是否存在等操作。需要说明的是,这些操作的时间复杂度为O
  • Set排序方法

    万次阅读 2019-04-22 21:04:28
    在讲解Set集合排序的几种方法之前,我们应该先清楚Set集合的几种类型以及特点,才能有效使用起来。 Set集合的特点 ​ Set不允许包含相同的元素,如果试图把两个相同元素加入同一个集合中,add方法返回false。 ​ ...
  • hashSet 是有序的吗、怎么保证唯一

    千次阅读 2020-08-05 15:57:52
    hashSet 是有序的吗?怎么保证元素唯一性? 本文带你了解
  • 幂等性问题通俗点讲就是保证数据不被重复消费,同时数据也不能少, 也就是数据一致性问题。 下面是MQ丢失的3种情况 1,生产者发送消息至MQ的数据丢失 解决方法:在生产者端开启comfirm 确认模式,你每次写的...
  • (十三)SET协议

    万次阅读 2021-07-23 15:29:26
    SET协议 安全电子交易协议(SET,Secure Electronic...它保证了开放网络上使用信用卡进行在线购物的安全,是一个专门针对于信用卡电子支付的安全协议,保证银行,商家和顾客之间的一致性和安全性问题,通过SET协议可以.
  • C++中set用法详解

    万次阅读 多人点赞 2018-06-02 22:28:10
    https://blog.csdn.net/yas12345678/article/details/526014541.关于setC++ STL 之所以得到广泛的赞誉,也被很多人使用,不只是提供了像vector, string, list等方便的容器,更重要的是STL封装了许多复杂的数据结构...
  • ES6中 Set 和 Map 数据结构以及Symbol

    千次阅读 2020-08-12 20:32:08
    ES6中 Set 和 Map 数据结构以及Symbol一、Set1、Set 实例的属性和方法2、遍历操作3、遍历的应用二、WeakSet三、Map1、Map实例的属性和操作方法2、遍历方法四、WeakMap五、SymbolSymbol声明的数据具有唯一性作为属性...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 288,570
精华内容 115,428
关键字:

set保证数据唯一