关于集合的笔记整理

集合笔记整理.doc 集合笔记 list arraylist集合 linkedlist集合 set hashset集合 treeset集合 map hashmap集合 terrset集合 不可变集合 立即下载

Collections:操作Collection、Map的工具类

 面试题:Collection 和 Collections 的区别?

public class CollectionsTest {
//发现一个不知对错的规律:如果方法是void没有返回值,那么这个方法的举措是在原数组上执行的,而不是新建一个数组执行,因而改变原数组
    /*
    reverse(List):反转List中元素的顺序
    shuffle(List):对List集合元素进行随机排序
    sort(List):根据元素的自然排序对指定List集合元素按升序排序
    sort(List,Comparator):根据指定的Comparator产生的顺序对List集合元素进行排序
    swap(List, int ,int):将指定List集合中的i处元素和j处元素进行交换

    Object max(Collection):根据元素的自然排序,返回给定集合中的最大元素
    Object max(Collection,Comparator):根据Comparator指定的顺序,返回给定集合中的最大元素
    Object min(Collection)
    Object min(Collection,Comparator)
    int frequency(Collection,Object):返回指定集合中指定元素的出现次数
    void copy(List dest,List src):将src中的内容复制到dest中
    boolean replaceAll(List list,Object oldAll,Object newVal):使用新值替换List对象的所有旧值

     */

    @Test
    public void test2(){
        List list = new ArrayList();
        list.add(123);
        list.add(43);
        list.add(765);
        list.add(-97);
        list.add(0);

        //错误写法报异常:IndexOutOfBoundsException: Source does not fit in dest
//        List dest = new ArrayList();先不初始化目的集合的容量,会报下标越界的错误
//        Collections.copy(dest,list);

        List dest = Arrays.asList(new Object[list.size()]);
        System.out.println(dest.size());////list.size();
        Collections.copy(dest,list);
        System.out.println(dest);

        /*
        Collections 类中提供了多个 synchronizedXxx()方法,
        该方法可使将指定集合包装成线程同步的集合,从而解决多线程并发访问集合时的线程安全问题

         */
    //返回的list1即为线程安全的List
        List list1 = Collections.synchronizedList(list);
    }

    @Test
    public void test1(){
        List list = new ArrayList();

        list.add(123);
        list.add(43);
        list.add(765);
        list.add(765);
        list.add(-97);
        list.add(0);

        System.out.println(list);

        Collections.reverse(list);
        System.out.println(list);

        Collections.shuffle(list);
        System.out.println(list);

        Collections.sort(list);
        System.out.println(list);

        Collections.swap(list,1,2);
        System.out.println(list);

        int frequency = Collections.frequency(list,765);
        System.out.println(frequency);//2
    }
}

一、集合框架的概述
* 1.集合、数组都是对多个数据进行存储操作的结构,简称Java容器
* 说明:此时的存储,主要指的是内存层面的存储,不涉及到持久化的存储(.txt .jpg .avi 数据库中)
*
*2.1 数组在存储多个数据方面的特点:
*   >一旦初始化以后,其长度就确定了
*   >数组一旦定义好,其元素的类型也就确定了。我们也就只能操作指定类型的数据了
*      比如:String[] arr; int[] arr1; Object[] arr2;
*2.2 数组在存储多个数据方面的缺点:
*    >一旦初始化以后,其长度就不可修改
*    >数组中提供的方法非常有限,对于添加、删除、插入数据等操作,非常不便,同时效率不高
*    >获取数组中实际元素的个数的需求,数组没有现成的属性或方法可用
*    >数组存储数据的特点:有序、可重复。对于无序、不可重复的需求,不能满足
*
* 二、集合框架
* |----Collection接口:单列集合,用来存储一个一个的对象
*    |----List接口:存储有序的、可重复的数据。 --->“动态”数组
*        |----ArrayList、LinkedList、Vector
*
*    |----Set接口:存储无序的、不可重复的数据  --->高中讲的"集合"
*        |----HashSet、LinkedHashSet、TreeSet
*
* |----Map接口:双列集合,用来存储一对(key - value)一对的数据  --->高中函数:y=f(x)
*    |----HashMap、LinkedHashMap、TreeMap、Hashtable、Properties
*
* 三、Collection接口中的方法的使用
public class CollectionTest {

    @Test
    public void test1(){
        Collection coll = new ArrayList();

        //add(Object e):将元素e添加到集合coll中
        coll.add("AA");
        coll.add("BB");
        coll.add(123);//自动装箱
        coll.add(new Date());

        //size():获取添加的元素的个数
        System.out.println(coll.size());//4

        //addAll(Collection coll1):将coll1集合中的元素添加到当前集合中
        Collection coll1 = new ArrayList();
        coll1.add(456);
        coll1.add("cc");
        coll.addAll(coll1);

        System.out.println(coll.size());//6
        System.out.println(coll);//相当于coll.toString()

        //isEmpty():判断当前集合是否为空
        System.out.println(coll.isEmpty());//false

        //clear():清空集合元素
        coll.clear();
        //此操作完成后,isEmpty()为true
    }
}

Collection接口中声明的方法的测试
* 结论:
* 向Collection接口的实现类的对象中添加数据obj时,要求obj所在类要重写equals()
public class CollectionTest1 {

    @Test
    public void test1() {
        Collection coll = new ArrayList();//以ArrayList作为collcetion接口的实现类
        coll.add(123);
        coll.add(456);
        coll.add(new String("Tom"));
        coll.add(false);
        coll.add(new Person("Jerry", 20));

        //contains(Object obj):判断当前集合是否包含obj
        //我们在判断时会调用obj对象所在类的equals()
        boolean contains = coll.contains(123);
        System.out.println(contains);//true
        System.out.println(coll.contains(new String("Tom")));//true
        System.out.println(coll.contains(new Person("Jerry", 20)));//false---->true(重写equals)
        //这里new Person是自定义类调用equals(),如果不重写则返回false

        //containsAll(Collection coll1):判断形参coll1中的所有元素是否都存在于当前集合中
        Collection coll1 = Arrays.asList(123, 456);//也可以用这种方法
        System.out.println(coll.containsAll(coll1));//true
    }

    @Test
    public void test2() {
        Collection coll = new ArrayList();//以ArrayList作为collcetion接口的实现类
        coll.add(123);
        coll.add(456);
        coll.add(new String("Tom"));
        coll.add(new Person("Jerry", 20));
        coll.add(false);
        //remove(Object obj):从当前集合中移除obj元素
        coll.remove(123);//remove()方法是boolean类型返回值,删除成功则返回true
                            //remove(123),首先要判断coll里面有没有123(涉及contains),所以要调用equals(),又是比较内容是否相等
                            //则要重写equals(),但这里的123是Interage包装类,包装类本身是自己重写equals()的,因此不用手动重写
        System.out.println(coll);//true
        coll.remove(new Person("Jerry", 20));
        System.out.println(coll);

        //removeAll(Collection coll1):差集: 从当前集合中移除coll1中所有元素
        Collection coll1 = Arrays.asList(123, 456);
        coll.removeAll(coll1);//直接在coll上做出改动
        System.out.println(coll1);
    }

    @Test
    public void test3() {
        Collection coll = new ArrayList();//以ArrayList作为collcetion接口的实现类
        coll.add(123);
        coll.add(456);
        coll.add(new String("Tom"));
        coll.add(new Person("Jerry", 20));
        coll.add(false);

//        //retainAll(Collection coll1):交集:获取当前集合和coll1集合的交集,并返回给当前集合
//        Collection coll1 = Arrays.asList(123, 456, 789);
//        coll.retainAll(coll1);
//        System.out.println(coll);

        //equals(Object obj):要想返回true,需要当前集合和形参集合的元素都相同
        Collection coll2 = new ArrayList();//以ArrayList作为collcetion接口的实现类
        coll2.add(123);
        coll2.add(456);

//        coll2.add(456);
//        coll2.add(123);
//如果添加的元素一样,顺序不一样,equals会false,因为跟ArrayList的有序性有关

        coll2.add(new String("Tom"));
        coll2.add(new Person("Jerry", 20));
        coll2.add(false);

        System.out.println(coll.equals(coll2));//如果上边的retainAll执行了,coll里的元素就不一样了,所以才要注释掉
    }

    @Test
    public void test4(){
        Collection coll = new ArrayList();//以ArrayList作为collcetion接口的实现类
        coll.add(123);
        coll.add(456);
        coll.add(new String("Tom"));
        coll.add(new Person("Jerry", 20));
        coll.add(false);

        //hashCode():返回当前对象的哈希值
        System.out.println(coll.hashCode());

        //集合--->数组:toArray()
        Object[] arr = coll.toArray();
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }

        //拓展:数组--->集合:调用Arrays类的静态方法asList()
        List list = Arrays.asList(new String[]{"AA", "BB","CC"});
//        List list1 = Arrays.asList("AA", "BB","CC");这样写就可以了

        System.out.println(list);

        List arr1 = Arrays.asList(new int[]{123,456});
        System.out.println(arr1.size());//1  这样写会识别为只有一个元素

        List arr2 = Arrays.asList(new Integer[]{123,456});
        System.out.println(arr2.size());//2

        //iterator():返回Iterator接口的实例,用于遍历集合元素。放在IteratorTest.java中测试
    }
}

 集合元素的遍历,使用迭代器Iterator接口

* 1.内部的方法:hasNext()和 next()
* 2.集合对象每次调用iterator()方法都得到一个全新的迭代器对象,默认游标都在集合的第一个元素之前
* 3.内部定义了一个remove(),可以在遍历的时候,删除集合中的元素。此方法不同于集合直接调用remove()
public class IteratorTest {
    @Test
    public void test1(){
        Collection coll = new ArrayList();//以ArrayList作为collcetion接口的实现类
        coll.add(123);
        coll.add(456);
        coll.add(new String("Tom"));
        coll.add(new Person("Jerry", 20));
        coll.add(false);

        Iterator iterator = coll.iterator();
//        //方式一
//        System.out.println(iterator.next());
//        System.out.println(iterator.next());
//        System.out.println(iterator.next());
//        System.out.println(iterator.next());
//        System.out.println(iterator.next());
//        System.out.println(iterator.next());

        //方式二 不推荐
//        for (int i = 0; i <coll.size() ; i++) {
//            System.out.println(iterator.next());
//        }

        //方式三 推荐
        while(iterator.hasNext()){ //hasNext()判断是否还有下一个元素
            //next():①指针下移②将下移以后集合位置上的元素返回
            System.out.println(iterator.next());
        }

//        //错误方式一:
//        Iterator iterator1 = coll.iterator();
//        while ((iterator1.next())!=null){
//            System.out.println(iterator.next());
//
//        }

//        //错误方式二
//        while (coll.iterator().hasNext()){
//            System.out.println(coll.iterator().next());
//        }
    }

        //测试Iterator中的remove()

//如果还未调用next()或在上一次调用next方法之后已经调用了remove方法,再调用remove会报IllegalStateException

    @Test
    public void test3(){
        Collection coll = new ArrayList();//以ArrayList作为collcetion接口的实现类
        coll.add(123);
        coll.add(456);
        coll.add(new String("Tom"));
        coll.add(new Person("Jerry", 20));
        coll.add(false);
        //删除集合中“Tom”
        Iterator iterator = coll.iterator();
        while (iterator.hasNext()){
            Object obj = iterator.next();
            if("Tom".equals(obj)){
                iterator.remove();
            }
        }
        //重新遍历集合
        iterator=coll.iterator();
            while (iterator.hasNext()){
                System.out.println(iterator.next());
            }
    }
}

* |----Collection接口:单列集合,用来存储一个一个的对象
*      |----List接口:存储有序的、可重复的数据。 --->“动态”数组(不用定义数组大小),替换原有数组
*          |----ArrayList:作为List接口的主要实现类;线程不安全,效率高;底层使用Object[]存储
*          |----LinkedList:对于频繁的插入、删除操作,使用此类操作效率比ArrayList高;底层使用双向链表存储
*          |----Vector:作为List接口的古老实现类;线程安全,效率低;底层使用Object[]存储
*
*面试题:ArrayList、LinkedList、Vector三者的异同?
* 同:三个类都实现了List接口,存储数据的特点相同:存储有序的、可重复的数据
* 不同:见上
* List接口中的常用方法
public class ListTest {
    /*
    void add(int index, Object ele):在indx位置插入ele元素
    boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来
    Object get(int index):获取指定index位置的元素
    int indexOf(Object obj):返回obj在集合中首次出现的位置
    int lastIndexOf(Object obj):返回obj在集合中末次出现的位置
    Object remove(int index):移除指定index位置的元素,并返回此元素
    Object set(int index, Object ele):设置指定index位置的元素为ele
    List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex位置的左闭右开子集合

    总结:常用方法
    增 add(Object obj)
    删 remove(int index) / remove(Object obj)
    改 set(int index, Object ele)
    查 get(int index)
    插 add(int index, Object ele)
    长度 size()
    遍历  ①Iterator迭代器方式
         ②增强for循环
         ③普通循环

     */
    @Test
    public void test3(){
        ArrayList list = new ArrayList();
        list.add(123);
        list.add(456);
        list.add("AA");

        //方式一:Iterator迭代器
        Iterator list1 = list.iterator();
        while (list1.hasNext()){
            System.out.println(list1.next());
        }

        //方式二:
        for(Object obj : list){//为什么是Object类型?因为ArrayList的底层就是Object[] elementData
            System.out.println(obj);
        }

        //方式三
        for (int i = 0; i <list.size() ; i++) {
            System.out.println(list.get(i));
        }
    }

    @Test
    public void test2(){
        ArrayList list = new ArrayList();
        list.add(123);
        list.add(456);
        list.add("AA");
        list.add(new Person("Tom",12));
        list.add(456);
//int indexOf(Object obj):返回obj在集合中首次出现的位置
        int index = list.indexOf(456);
        System.out.println(index);//1 不存在则返回-1

// int lastIndexOf(Object obj):返回obj在集合中末次出现的位置
        int index1 = list.lastIndexOf(456);
        System.out.println(index1);//4

// Object remove(int index):移除指定index位置的元素,并返回此元素
        Object obj = list.remove(1);
        System.out.println(obj);//456
        System.out.println(list);//[123, AA, Person{name='Tom', age=12}, 456]

// Object set(int index, Object ele):设置指定index位置的元素为ele
        System.out.println(list);//[123, AA, Person{name='Tom', age=12}, 456]
        list.set(1,"CC");
        System.out.println(list);//[123, CC, Person{name='Tom', age=12}, 456]

// List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex位置的子集合
        List subList = list.subList(2, 4);
        System.out.println(subList);//[Person{name='Tom', age=12}, 456]

        System.out.println(list);
    }

        @Test
    public void test1(){
            ArrayList list = new ArrayList();
            list.add(123);
            list.add(456);
            list.add("AA");
            list.add(new Person("Tom",12));
            list.add(456);

            System.out.println(list);//[123, 456, AA, Person{name='Tom', age=12}, 456]

            //void add(int index, Object ele):在indx位置插入ele元素
            list.add(1,"BB");
            System.out.println(list);//[123, BB, 456, AA, Person{name='Tom', age=12}, 456]

//boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来
            List list1 = Arrays.asList(1, 2, 3);//Collection eles
            list.addAll(2,list1);//也可以不写index,则默认将list1加到最后面
            System.out.println(list);//[123, BB, 1, 2, 3, 456, AA, Person{name='Tom', age=12}, 456]


            System.out.println(list.size());//6+3

//            list.add(list1);//把list1里面的元素识别成1个了
//            System.out.println(list.size());//6+1

//            Object get(int index):获取指定index位置的元素
            System.out.println(list.get(1));

        }
}

 

一、Map的实现类的结构
* |---Map:双列数据,用于存储key-value对的数据  ---类似于高中的函数:y=f(x)
*      |---HashMap:作为Map的主要实现类;线程不安全的,效率高;存储null的key和value
* (HashMap的子类)|---LinkedHashMap:保证在遍历map元素时,可以按照添加的顺序实现遍历
*                      原因:在原有的HashMap底层结构基础上,添加了一对指针,指向前一个和后一个元素
*                       对于频繁的遍历操作,此类执行效率高于HashMap
*      |---TreeMap:保证按照添加的key-value对进行排序,实现排序遍历。此时考虑key的自然排序或定制排序
*                   底层使用红黑树
*      |---Hashtable:作为古老的实现类;线程安全,效率低;不能存储null的key和value
*         |---Properties:常用来处理配置文件。key和value都是String类型
*
*
*
*      HashMap的底层:数组+链表(jdk7及之前)
*                    数组+链表+红黑树(jdk8)
*
* 面试题:
* 1.HashMap的底层实现原理?
* 2.HashMap和Hashtable的异同?
* 3。CurrentHashMap和Hashtable的异同?
*
* 二、Map结构的理解
*   Map中的key:无序的、不可重复的,使用Set存储所有的key --->key所在的类要重写equals()和hashCode() (以hashMap为例)
*   Map中的value:无序的、可重复的,使用Collection存储所有的value--->value所在的类要重写equals()
*   一个键值对:key-value构成一个Entry对象
*   Map中的entry:无序的、不可重复的,使用Set存储所有的entry
*
*
* 三、HashMap的底层实现原理?以jdk7为例说明:
*      HashMap map = new HashMap();
*      在实例化以后,底层创建了长度为16的一维数组Entry[] table
*      ...可能已经执行过多次put...
*      map.put(key1,value1):
*      首先,调用key1所在类的hashCode()计算key1哈希值,此哈希值经过某种算法计算后,得到在Entry数组中的存放位置。
*      如果此位置上的数据为空,此时的key1-value1添加成功。 --->情况1
*      如果此位置上的数据不为空,(意味着此位置上存在一个或多个数据(以链表的形式存在)),比较key1和已经存在的一个或多个数据
*      的哈希值:
*              如果key1的哈希值与已经存在的数据的哈希值都不相同,此时key1-value1添加成功。 --->情况2
*              如果key1的哈希值与已经存在的某一个数据(key2-value2)的哈希值相同,继续比较;调用key1所在类的equals(key2)方法
*                      如果equals()返回false:此时key1-value1添加成功。 --->情况3
*                      如果equals()返回true:使用value1替换value2
*
*    补充:关于情况2和情况3:此时key1-value1和原来的数据以链表的方式存储。
*
*    在不断的添加过程中,会涉及到扩容问题,当超出临界值(且要存放的位置非空)时,扩容。
*    默认的扩容方式:扩容为原来容量的2倍,并将原有的数据复制过来
*
*    jdk8 相较于jdk7在底层实现方面的不同:
*    1.new HashMap():底层没有创建一个长度为16的数组
*    2.jdk8底层的数组是:Node[],而非Entry[]
*    3.首次调用put()方法时,底层创建长度为16的数组
*    4.jdk底层结构只有:数组+链表。jdk8中底层结构:数组+链表+红黑树
*      当数组的某一个索引位置上的元素以链表形式存在的数据个数 > 8 且当前数组的长度 > 64时,
*      此时此索引位置上的所有数据改为使用红黑树存储
*
*
*      DEFAULT_INITIAL_CAPACITY:HashMap的默认容量,16
*      DEFAULT_LOAD_FACTOR:HashMap的默认加载因子:0.75
*      threshold:扩容的临界值=容量*填充因子=16*0.75=>12
*      TREEIFY_THRESHOLD:Bucket中链表长度大于该默认值,转化为红黑树:8
*      MIN_TREEIFY_CAPACITY:桶中的Node被树化时最小的hash表容量:64
*
* 四、LinkHashMap的底层实现原理(理解)
*
* 五、Map中定义的方法:
* 添加、删除、修改操作:
* Object put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中
* void putAll(Map m):将m中的所有key-value对存放到当前map中
* Object remove(Object key):移除指定key的key-value对,并返回value
* void clear()清空当前map中的所有数据
* 元素查询的操作:
* Object get(Object key):获取指定key对应的value
* boolean containsKey(Object key):是否包含指定的key
* boolean containsValue(Object value):是否包含指定的value
* int size():返回map中key-value对的个数
* boolean isEmpty():判断当前map是否为空
* boolean equals(Object obj):判断当前map和参数对象obj是否相等
* 元视图操作方法:
* Set keySet():返回所有key构成的Set集合
* Collection values():返回所有value构成的Collection集合
* Set entrySet():返回所有key-value对构成的Set集合
*
*
* 总结:常用方法:
* 添加:put(Object key,Object value)
* 删除:remove(Object key)
* 修改:put(Object key,Object value)
* 查询:get(Object key)
* 长度:size()
* 遍历:keySet()、values()、entrySet()
public class MapTest {
    /*
    元视图操作方法:
 * Set keySet():返回所有key构成的Set集合
 * Collection values():返回所有value构成的Collection集合
 * Set entrySet():返回所有key-value对构成的Set集合
     */
    @Test
    public void test4(){
        HashMap map = new HashMap();
        map.put("AA",123);
        map.put(45,1234);
        map.put("BB",56);

        //遍历所有的key集:keySet()
        Set set = map.keySet();
        Iterator iterator = set.iterator();
        while (iterator.hasNext()){
            System.out.println(iterator.next());
        }

        //遍历所有的value集:values()
        Collection values = map.values();
        Iterator iterator1 = values.iterator();
        //也可以用增强for
        while (iterator1.hasNext()){
            System.out.println(iterator1.next());
        }

        ////遍历所有的key-value
        //方式一:entrySet()
        Set entrySet = map.entrySet();
        Iterator iterator2 = entrySet.iterator();
        while (iterator2.hasNext()){
            Object obj = iterator2.next();
            //entrySet集合中的元素都是entry
            Map.Entry entry = (Map.Entry)obj;
            System.out.println(entry.getKey() + "--->" + entry.getValue());
        }
        System.out.println();

        //方式二:
        Set keySet = map.keySet();
        Iterator iterator3 = set.iterator();
        while (iterator3.hasNext()){
        Object key = iterator3.next();
        Object value = map.get(key);
            System.out.println(key + "--->" + value);
        }
    }

    /*
    元素查询的操作:
 * Object get(Object key):获取指定key对应的value
 * boolean containsKey(Object key):是否包含指定的key
 * boolean containsValue(Object value):是否包含指定的value
 * int size():返回map中key-value对的个数
 * boolean isEmpty():判断当前map是否为空
 * boolean equals(Object obj):判断当前map和参数对象obj是否相等
     */
    @Test
    public void test3() {
        HashMap map = new HashMap();
        map.put("AA",123);
        map.put(45,123);
        map.put("BB",56);
//    Object get(Object key):获取指定key对应的value
        System.out.println(map.get("AA"));//123

//   boolean containsKey(Object key):是否包含指定的key
        System.out.println(map.containsKey(45));//true

//   boolean containsValue(Object value):是否包含指定的value
        System.out.println(map.containsValue(123));//true

//     int size():返回map中key-value对的个数
        int size = map.size();
        System.out.println(size);//3

//  boolean isEmpty():判断当前map是否为空
        System.out.println(map.isEmpty());//false

//  boolean equals(Object obj):判断当前map和参数对象obj是否相等
        HashMap map1 = new HashMap();
        map1.put("AA",123);
        map1.put(45,123);
        map1.put("BB",56);
        System.out.println(map.equals(map1));//true
    }

    /*
    添加、删除、修改操作:
 * Object put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中
 * void putAll(Map m):将m中的所有key-value对存放到当前map中
 * Object remove(Object key):移除指定key的key-value对,并返回value
     */
    @Test
    public void test2(){
        HashMap map = new HashMap();
        //添加
        map.put("AA",123);
        map.put(45,123);
        map.put("BB",56);
        //修改
        map.put("AA",87);

        System.out.println(map);//{AA=87, BB=56, 45=123}

        HashMap map1 = new HashMap();
        map1.put("CC",123);
        map1.put("DD",123);
        map.putAll(map1);

        System.out.println(map);//{AA=87, BB=56, CC=123, DD=123, 45=123}

   //remove(Object key)
        Object value = map.remove("CC");
        //如果remove的key不存在,返回的value是null
        System.out.println(value);//123
        System.out.println(map);//{AA=87, BB=56, DD=123, 45=123}

        //clear()
        map.clear();//与map=null;操作不同
        System.out.println(map.size());//0
        System.out.println(map);//{}
    }

    @Test
    public void test1(){
        HashMap map = new HashMap();
        map.put(null,123);
        //Hashtable中不能存储null
    }
}

 


* 1.Set接口的框架
* |----Collection接口:单列集合,用来存储一个一个的对象
*  *    |----Set接口:存储无序的、不可重复的数据  --->高中讲的"集合"
*  *        |----HashSet:作为Set接口的主要实现类;线程不安全;可以存储null值
*                 |----LinkedHashSet:HashSet的子类;遍历其内部数据时,可以按照添加的顺序遍历
*                                      对于频繁的遍历操作:LinkedHashSet效率高于HashSet
*           |----TreeSet:可以按照添加的对象的指定属性,进行排序。
*
*1.Set接口中没有额外定义的新方法,使用的都是Collection中声明过的方法
*
*2.要求:向Set中添加的数据,其所在类一定要重写hashCode()和equals()
*  要求:重写的hashCode()和equals()尽可能保持一致性:相等的对象必须具有相等的散列码
*        重写两个方法的小技巧:对象中用作equals()方法比较的Field,都应该用来计算hasCode值

一、Set:存储无序的、不可重复的数据

以HashSet为例说明:
1.无序性:不等于随机性。存储的数据在底层数组中并非按照数组索引的顺序添加。而是根据数据的哈希值决定的

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

二、添加元素的过程:以HashSet为例:
    我们向HashSet中添加元素a,首先调用元素a所在类的hashCode()方法,计算元素a的哈希值,
    此哈希值接着通过某种算法计算出在HashSet底层数组中的存放位置(即为:索引位置),判断
    数组此位置上是否已经有元素:
           如果此位置上没有其他元素,则元素a添加成功。————>情况1
           如果此位置上有其他元素b(或以链表形式存在的多个元素),则比较元素a与元素b的hash值:
                如果hash值不相同,则元素a添加成功  ————>情况2
                如果hash值相同,进而需要调用元素a所在类的equals()方法:
                        equals()返回true,则元素a添加失败
                        equals()返回false,则元素a添加成功————>情况3

    对于添加成功的情况2和情况3而言:元素a与已经存在指定索引位置上数据以链表的方式存储
    jdk 7 :元素a放到数组中,指向原来的元素
    jdk 8 :原来的元素在数组中,指向元素a
    总结:七上八下

    HashSet底层:数组+链表的结构(前提 jdk7)
public class SetTest {
 @Test
    public void test1() {
        Set set = new HashSet();
        set.add(465);
        set.add(123);
        set.add("AA");
        set.add("CC");
        set.add(new User("Tom", 12));
        set.add(129);

        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
//            AA
//            CC
//            465
//            129
//            123
//            Person{name='Tom', age=12}
        }
    }

    //LinkedHashSet的使用
    //LinkedHashSet作为HashSet的子类,在添加数据的同时,每个数据还维护了两个引用,记录此数据前一个数据和后一个数据
    //优点:对于频繁的遍历操作:LinkedHashSet效率高于HashSet
    @Test
    public void test2() {
        Set set = new LinkedHashSet();
        set.add(465);
        set.add(123);
        set.add("AA");
        set.add("CC");
        set.add(new User("Tom", 12));
        set.add(129);

        Iterator iterator = set.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
        }
    }
}

 

 

[Windows] 发票识别工具。支持xml、pdf、ofd文件。 发票识别是财务自动化中的关键环节,支持多种格式(XML、PDF、OFD)的识别工具能显著提升工作效率。以下介绍基于Windows平台开发此类工具的技术方案。发票识别是财务自动化中的关键环节,支持多种格式(XML、PDF、OFD)的识别工具能显著提升工作效率。以下介绍基于Windows平台开发此类工具的技术方案。 阅读详情

相关推荐

FX2N-2AD模块实战:从硬件连接到FROM/TO指令编程详解

本文详细解析FX2N-2AD模拟量输入模块的硬件连接与FROM/TO指令编程技巧,涵盖BFM缓冲存储器配置、梯形图程序设计及工程实战经验。通过实例演示如何实现精准信号采集与数据处理,特别针对PLC系统中的常见故障提供解决方案,助力工业自动化工程师高效完成设备调试与维护。

prometheus9mon的博客 510

个人关于集合学习的笔记(超详细)

本文章干货内容过多,不易消化

2203_75851285的博客 495

麒麟V10 SP3国产化环境部署MySQL 8.0全流程实战

本文详细介绍了在国产化操作系统麒麟V10 SP3上部署MySQL 8.0的全流程实战指南。从环境准备、冲突排查到安装包处理、服务配置与安全加固,提供了详细的命令和技巧,帮助用户顺利完成MySQL 8.0的部署与优化,适用于国产化环境下的数据库应用。

weixin_29231027的博客 274

集合论知识总结——集合及其运算

集合论知识总结

m0_62249876的博客 9536

Blender三渲二全流程实战:从建模到输出的完整管线

三渲二是非真实感渲染(NPR)的重要分支,通过三维建模、卡通材质、硬朗灯光与描边技术,输出具有手绘质感的画面。其核心原理在于使用Shader to RGB与ColorRamp构建色阶过渡,配合壳模型描边模拟动画线条。该技术可在动漫、游戏CG、广告等场景复用三维资产,兼顾手绘风格与制作效率。对于希望掌握卡通渲染流程的开发者而言,Blender提供了从建模、材质、灯光到渲染合成的全套工具链。本文以一把太刀展示动画为例,完整演示低模搭建、Toon材质节点、壳模型描边、三点布光、序列帧输出与视频合成,帮助读者建立一

weixin_26767391的博客 288

VGG16

VGG16学习笔记

一去不复返的通信er 1178

常用集合知识笔记(全)

集合 可以分为两大类:Collection和Map,其中Collection是一个个存放数据的,而Map是一对一对存放数据的 Collection是一个接口,有两个重要的子接口:List和Set,其中List是有序的可以重复的,Set是无序的不可重复的 List接口重要的实现类:ArrayList、LinkedList、Vector(已淘汰) Set接口重要的实现类:HashSet(重要)、TreeSet Collection接口实现类的特点: 1.Collection的实现类可以存放多个元素,每个元素可以

qq_51097279的博客 1290

ANSYS Fluent中的声学模型:实用指南

文章摘要 本文介绍了ANSYS Fluent中三种气动声学模拟方法:Ffowcs-Williams & Hawkings(FWH)模型、宽带噪声源模型和波动方程模型。FWH模型适用于外部气动声学问题,需要瞬态流场数据来预测远场噪声;宽带模型基于稳态RANS模拟,可快速识别噪声源位置,适合早期设计阶段;波动方程模型直接求解声波方程,提供全域声压分布,但仅适用于低马赫数流动。文章详细说明了各模型的使用场景、设置步骤和关键参数配置,为工程应用提供了实用指南。

weixin_45793544的博客 1325

集合总结的笔记

集合 首先就是集合和数组的区别: 1、长度可变性:数组定义时需要指定长度,长度不可变;集合定义时不需要指定长度,长度可变。 2、存放的数据类型:数组可以存放基本数据类型的数据也可以存放引用数据类型的数据;集合只能存放引用数据类型的数据(但是基本数据类型可以自动装箱为引用数据类型,然后存进去)。 3、元素类型:数组在定义时需要指定元素类型,定义后数组只能存放该数据类型的数据;集合定义时可以不指定数据类型,可以存放不同引用数据类型的数据。 集合分类 Collection 单列集合的顶层接口 ├——-List 接

Nazi_的博客 447

使用GBIF获取生物多样性数据与GIS的结合

随着全球生物多样性的重要性日益凸显,越来越多的研究人员和保护机构开始利用地理信息系统(GIS)来分析和可视化生物多样性数据。GBIF(全球生物多样性信息设施)作为一个全球性的生物多样性数据库,提供了大量的物种分布和分类信息,为研究人员和保护工作者提供了宝贵的数据资源。本文将介绍如何使用GBIF API获取生物多样性数据,并将其与GIS技术相结合,以便更好地理解和研究生物多样性。利用GIS的强大功能,我们可以在地理空间上可视化物种分布、分析物种多样性的空间格局,并为保护生物多样性提供科学依据。

BnxBackend的博客 1765

STM32_HAL库—PWM产生指定个数

(一)CubeMX设置: 1. 晶振配置(72M) 2. 引脚配置 3. 中断配置 4. 配置及实现方式 由上推出公式: 机器周期: (72MHz / 36) = 2MHz = 0.5us PWM周期: 0.5 * 100 = 50us = 20kHz 5. 主函数调用PWM函数 HAL_TIM_PWM_Start_IT(&htim3, TIM_CHANNEL_2); //此处一句后可直接进入中断 6. PWM溢出回调函数 void HAL_TIM_PWM_PulseFinished

5527

集合复习笔记(上)

集合复习笔记上,讲解集合的基础,并不深入

qq_51606563的博客 551

【OpenClaw从入门到精通】第45篇:Skill供应链安全——如何识别并避开恶意技能插件?(2026实测版)

随着OpenClaw生态爆发式增长,全球Skills总量近75万个,日均新增2.1万个,但恶意/问题插件已超600个,数十万用户受影响。本文基于奇安信威胁报告及360安全实践,拆解恶意技能的五大核心特征,提出"安装前三步法"安全审查流程,详解安全技能来源白名单与定期审计方案,并深度解析360龙虾Skill安全超市的分级认证机制。读者可掌握从技能筛选、安装审查到术后审计的全流程安全防护手段,通过实操命令与案例演示,零成本构建Skill供应链安全防线,避免遭遇私钥窃取、资产损失等安全事件。

专注于人工智能、软件开发、工控自动化、工厂数字化及智能化等领域,希望和大家共同进步! 564

Java集合容器整理笔记05

Java集合容器整理笔记05

xlshi1996的博客 165

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

Java集合容器整理笔记04

Java集合容器整理笔记04

xlshi1996的博客 139

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

Java集合容器整理笔记03

Java集合容器整理笔记03

xlshi1996的博客 165

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Java集合容器整理笔记02

Java集合容器整理笔记02

xlshi1996的博客 156

集合类的笔记整理

目录 集合 集合类的概念 List集合 Set集合 集合 集合类的概念 Java提供了一些类,这些类相当于容器,能够存储一系列的对象的引用,统称为集合类,其中存储的每个内容称为元素。 集合中的接口有两个,分别是collection接口和map接口。 方法 功能描述 add(E e) 将指定元素添加到集合,E代指该集合中储存元素的类型 addAll(Collection<? extends E> e) 将指定集合全部添加...

qq_59227724的博客 578

常用集合整理笔记

1.集合 定义 是一个长度可变的容器; 数组是唯一的底层容器; 只能存储引用数据类型;存储基本数据类型会自动装箱变成包装类对象. 分类 Collection集合:单列集合; List集合:有序可重复 Set集合:无序不可重复 Map集合:单列集合 常用方法: add(E) add(index,E) 添加元素 remove(index) remove(E) 删除元素 set(index,E)改 get(index)查 indexOf(E) lastIndexOf() c

weixin_45590934的博客 452

集合框架整理笔记

List 存放的数据可以重复,并且有顺序 ArrayList 底层是Object[]数组 增删很慢,查询很快 初始容量为10 方法 返回值 描述 add(Object o) boolean 将指定的元素添加 addAll(Collection c) boolean 按照指定 collection 的迭代器所返回的元素顺序,将该 collection 中的所有元素添加到此列表的尾...

CodeV的博客 408

java集合整理笔记

java集合 集合框架: collection与map 针对collection: list set 和 queue两端出入的list 所以也可以用数组或链表来实现 针对map来说: Hashmap hashtable TreeMap list是有序的Collection 包括三个实现类有分别是 ArrayList: 排列有序可重复 底层使用数组 查询速度快但增删慢 getter()和setter() 方法快 线程不安全 当容量不够的时候 ArrayList是当前容量*1.5+1. vevtor:不

初学者的java之旅 287

java整理笔记之集合

特点: 1:对象封装数据,对象多了也需要存储。集合用于存储对象。 2:对象的个数确定可以使用数组,但是不确定怎么办?可以用集合。因为集合是可变长度的。   集合和数组的区别: 1:数组是固定长度的;集合可变长度的。 2:数组可以存储基本数据类型,也可以存储引用数据类型;集合只能存储引用数据类型。 3:数组存储的元素必须是同一个数据类型;集合存储的对象可以是不同数据类型。   数据

说:/~不了的专栏 499

整理笔记_集合_Collection

集合 概述: 集合是JAVA中提供的一种容器,可以用来存储多个数据。 集合与数组的区别: 1. 数组的长度是固定的,集合的长度是可变的。 2. 数组存储的是同一类型的元素,可以存储基本数据类型, 集合中存储的都是对象,而且对象的类型可以不一致。 java.util.Collection接口: 此接口是所有单例集合的最顶层接口,定义了所有单例集合共性的方法。 任意单列集合都可...

weixin_46016613的博客 218

Java集合整理笔记

个人闲暇时整理的Java集合相关笔记,第一部分是简单理解一下基本概念,第二部分是总结十道常考面试题。个人能力有限,文字比较主观,如有描述不当敬请指正~

是袁同学呀 863

JAVA集合整理笔记

参考 Java集合类: Set、List、Map、Queue使用场景梳理 https://www.cnblogs.com/LittleHann/p/3690187.html

weixin_42489648的博客 350

Java集合类复习整理

先写在这吧,等之后有时间了系统复习下Java的集合类整理下笔记加深下印象什么的....

。 375
上一篇: 关于多线程(杂项)
下一篇: 关于Mybatis的bind标签
saving178
博客等级 码龄8年 0粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值