zoukankan      html  css  js  c++  java
  • 11Java集合

    Java集合

     HashSet集合

     补充:hashCode()相同,但equals()不一定相同(大部分都是相同);hashCode()不相同,那equals()一定不相同;如果equals()不相同,但hashCode()有可能相同(小概率)。底层原理暂时没理解,详细可以点击:这里

    所以重写equals的时候,有必要重写hashCode(),保证数据唯一性,即:equals相同时,hashCode也相同;hashCode()相同时,equals也相同,达成充要条件。

    HashSet相关方法

     Collection集合遍历的Iterator迭代器

     for each增强循环

    hashCode()方法

     补充:hashSet的底层是通过hashMap实现的,hashMap的put()方法实现:会先比较hashCode,再比较equals。

    之所以先比较hashCode是因为每个引用类型的数据都是根据hashCode()存储的,hashCode()把数据分到了不同区域,这样比较的时候可以迅速的找到hashCode计算的哈希值找到同一的区域,不用遍历整个集合浪费时间。

     例子

    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Set;
    /**
     * 
     * @author leak
     *    HashSet集合的常用方法
     */
    public class Test4 {
        public static void main(String[] args) {
            Set set = new HashSet();
            //集合里面存储都是引用类型
            //add()方法添加元素进集合
            set.add(1);//这里虽然存储了基本数据类型,但是会自动转为包装类存储
            set.add("a");
            System.out.println(set);
            
            //remove()移除集合元素
            set.remove(1);
            System.out.println(set);
            
            //contains()判断集合是否包含该值,返回布尔类型
            System.out.println(set.contains("a"));
            
            //clear()清空集合所有元素
            set.clear();
            System.out.println(set);
            
            //集合遍历
            set.add("a");
            set.add("b");
            set.add("c");
            set.add("d");
            
            set.add("d");//set集合存的值是不重复的
            System.out.println("大小还是:"+set.size());
            set.add(null);//集合可以存储null
            //输出set集合,可以看出排序是根据hashCode()排序
            //set集合是无顺序存储的
            System.out.println(set);
            
            //从这里可以看出set集合可以存储不同引用类型的对象
            set.add(1);
            set.add(true);
            set.add(null);
            
            //方法一:使用迭代器遍历集合
            //创建迭代器对象
            Iterator it = set.iterator();
            //hasNext()判断是否存在元素
            while(it.hasNext()) {
                //存在,则打印输出
                System.out.println(it.next());
            }
            //方法二:for each增强循环
            //set集合里面的每一个元素赋值给o变量
            for(Object o : set) {
                System.out.println(o);
            }
            
            //集合的大小,数组是长度length,集合是size
            System.out.println(set.size());//获取集合的元素个数    
        }
    }
    View Code

    泛型

    Collection集合可以存储不同的引用数据类型,那么如果只想用存储一种引用类型的集合,那怎么办呢?就需要用到泛型来约束集合存储的类型。(补充:无论泛型是哪种,add()方法都可以添加null,但是还是不要添加null进去,有些类型会报空指针异常)

    泛型指定集合的数据类型,但是泛型只能指定引用数据类型,不能指定基本数据类型。

    public class Test5 {
        public static void main(String[] args) {
            //泛型,集合可以通过泛型指定引用数据类型
            //注意:泛型只能使用引用数据类型,不能使用基本数据类型
            //指定String为集合的泛型,那么这个集合不能存String类型之外类型,否则报错
            Set<String> set = new HashSet<String>();
            set.add("a");
            set.add("b");
            //下面的三种类型都会报错,因为set集合已经使用了泛型String约束
    //        set.add(1);Set<String> set = new HashSet<String>();
    //        set.add(true);
    //        set.add('a');
            
            //补充:Set<Object> set = new HashSet<Object>();
            // 等同于  Set set = new HashSet();这里省略了泛型就是Object
        }
    }

    TreeSet集合

     TreeSet默认的自然排序

     TreeSet集合是通过compareTo()方法进行排序,对集合中的元素从小到大排序(正序)。

    import java.util.Iterator;
    import java.util.Set;
    import java.util.TreeSet;
    
    public class Test6 {
        public static void main(String[] args) {
            //TreeSet默认自然排序,也就是有序存储
            //TreeSet的增删 包含 清空方法都是和hashSet一致,迭代器,for each都是
            //这里泛型类型指定Integer,只能存储Integer类型,基本的数据类型int会自动转为包装类
            Set<Integer> set = new TreeSet<Integer>();
            set.add(1);
    //        set.add(1.21);//会报错
            set.add(2);
            set.add(9);
            set.add(4);
            set.add(3);
            System.out.println(set);//TreeSet自然排序
            
            //增加元素
            set.add(129);
            System.out.println(set);
            
            //删除元素
            set.remove(32);
            System.out.println(set);
            
            //判断是否元素存在于集合
            System.out.println(set.contains(32));
            
            //清空集合
            set.clear();
            System.out.println(set);
            
            //集合的大小,数组是length
            System.out.println(set.size());
            
            //方法一:使用迭代器遍历集合
                //创建迭代器对象
                Iterator it = set.iterator();
                //hasNext()判断是否存在元素
                while(it.hasNext()) {
                    //存在,则打印输出
                    System.out.println(it.next());
                }
                
            //方法二:for each增强循环
                //set集合里面的每一个元素赋值给o变量
                for(Object o : set) {
                    System.out.println(o);
                }
        }
    }
    View Code

    TreeSet定制排序

    如果需要实现定制排序,则需要在创建 TreeSet 集合对象时,提供一个 Comparator 接口的实现类对象。由该 Comparator 对象负责集合元素的排序逻辑。

    import java.util.Comparator;
    import java.util.Set;
    import java.util.TreeSet;
    
    public class Test7 {
        public static void main(String[] args) {
            Set<Person> set = new TreeSet<Person>(new Person());
            Person p1 = new Person(12,"ds");
            Person p2 = new Person(22,"asd");
            Person p3 = new Person(34,"dbd");
            Person p4 = new Person(232,"dwe");
            Person p5 = new Person(11,"osb");
            set.add(p1);
            set.add(p2);
            set.add(p3);
            set.add(p4);
            set.add(p5);
            //遍历打印
            for(Person p : set) {
                System.out.println(p.age+"  "+p.name);
            }
        }
    }
    
    //定制逻辑排序,为什么实现Comparator要用类呢,因为比较只能比较同一类型
    //所以要使用一个类去实现Comparator接口,才能重写里面的compare比较方法
    //不同类型,比较的内容不一样,所以要使用类来实现Comparator接口
    class Person implements Comparator<Person>{
        int age;
        String name;
        public Person() {}
        public Person(int age,String name) {
            this.age = age;
            this.name = name;
        }
        
        //定制排序逻辑在compare方法中实现
        //接口必须重写的方法
        @Override
        public int compare(Person o1, Person o2) {
            //正序排序,从小到大,正序和倒序区别,比较下面的就知道了
            if(o1.age > o2.age) {
                return 1;
            }else if(o1.age < o2.age) {
                return -1;
            }else {
                return 0;
            }
        }
        
    //    @Override
    //    public int compare(Person o1, Person o2) {
    //        //倒序排序,从大到小 ,区别在于 o1.age和o2.age相比返回什么,1/-1
    //        if(o1.age < o2.age) {
    //            return 1;
    //        }else if(o1.age > o2.age) {
    //            return -1;
    //        }else {
    //            return 0;
    //        }
    //    }
    }
    View Code

    List和ArrayList

     例子

    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 
     * @author leak
     *    ArrayList和HashSet是相反的
     *    ArrayList是有序,且元素可重复
     *    HashSet是无序,且元素不重复
     */
    public class Test8 {
        public static void main(String[] args) {
            List<String> list = new ArrayList<String>();
            //ArrayList的add方法默认按照添加元素顺序存储(有序)
            list.add("A");//第一个,索引下标0
            list.add("B");//索引下标1
            list.add("C");//索引下标2
            list.add("D");//索引下标3
            list.add("A");//索引下标4,运行使用重复元素
            
            System.out.println(list);
            //get(index)根据索引下标获取元素
            System.out.println(list.get(2));//通过索引访问指定位置的集合元素
            
            //add(index,value)可以指定位置添加元素
            //add(value)
            list.add("a");
            list.add(2,"df");//指定索引下标位置插入数据
            System.out.println(list);
            
            //ArrayList集合合并
            List<String> list1 = new ArrayList<String>();
            list1.add("1");
            list1.add("2");
            //addAll(value)默认插入到最后位置
            //addAll(index,value)指定索引位置插入
            list.addAll(2,list1);//把一个集合添加进集合里面
            System.out.println(list);
            
            //indexOf(value)获取指定元素在集合中第一次出现的下标
            //lastIndexOf(value)获取指定元素在集合中最后一次出现的下标
            System.out.println(list.indexOf("A"));//0
            System.out.println(list.lastIndexOf("A"));//7
            
            //remove(index)根据指定的索引下标移除元素
            list.remove(0);
            System.out.println(list);
            
            //set(index,value)根据指定索引下标,修改元素
            list.set(0,"A");
            System.out.println(list);
            
            //subList(start,end)根据索引下标截取指定范围的集合元素
            //这里的end不包含结束,也就是(2,4)只包含了2,3
            List<String> sublist = list.subList(2, 4);
            System.out.println(sublist);
            
            //集合大小
            System.out.println(list.size());
        }
    }
    View Code

    补充:

    Set/List小总结:Set集合是无序,且不可重复;List集合是有序,且可重复。(也就是set和list集合是相反的)通常说的set集合值的是hashSet集合,TreeSet是有序,且不可重复。通常的list集合是说ArrayList集合。

    Map集合

     Map接口和HashMa集合常用方法

    例子

    import java.util.Collection;
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;
    
    /**
     * 
     * @author leak
     *    map集合
     *    通常的map集合指的是HashMap
     *
     */
    public class Test9 {
        public static void main(String[] args) {
            Map<String,Integer> map = new HashMap<String,Integer>();
            
            //put(key,value)键值对添加元素
            map.put("b",1);
            map.put("c",3);
            map.put("e",2);
            System.out.println(map);
            
            //get(key)根据key取value的值
            System.out.println(map.get("e"));
            
            //remove(key)根据key移除键值对
            System.out.println(map.remove("c"));
            
            //size()获取集合的大小
            System.out.println(map.size());
            
            //containsKey(key)根据key判断集合是否存在该key
            System.out.println(map.containsKey("b"));
            
            //containsValue(value)根据value判断集合是否存在该value
            System.out.println(map.containsValue(2));
            
            //clear()清空集合map.clear()
            
            //遍历map集合,通过map.keySet()方法获取key的集合
            Set<String> keys = map.keySet();//使用set接口存储map的key集合
            //遍历map集合,二次取值,根据key取value
            for(String key : keys) {
                System.out.println("key: "+key+" value: "+map.get(key));
            }
            
            System.out.println();
            
            //通过map.entrySet()返回键值对所有的集合
            //entrySet返回的键值对集合就是一个个的map集合,类似二维数组存储方式
            Set<Entry<String,Integer>> entrySet = map.entrySet();
            for(Entry<String,Integer> entry : entrySet) {
                System.out.println("key: "+entry.getKey()+" value: "+entry.getValue());
            }
            
            System.out.println();
            
            //遍历map集合的所有value
            //map.values()获取集合的所有value的元素,不包含key
            Collection<Integer> values = map.values();
            for(Integer value : values) {
                System.out.print("value: "+value+" ");
            }
            System.out.println();
        }
    }
    View Code

     HashMap和Hashtable

     TreeMap

     TreeMap和TreeSet差不多,都是有序。只有可重复/不可重复的区别。

    import java.util.Map;
    import java.util.TreeMap;
    /**
     * 
     * @author leak
     *    TreeMap默认自然排序,数字比字母优先级高,先按照数字排完才到字母排序,是根据key排序
     */
    public class Test10 {
        public static void main(String[] args) {
            //TreeMap的自然排序是字典排序
            Map<Integer,String> map = new TreeMap<Integer,String>();
            map.put(4,"a");
            map.put(2,"a");
            map.put(3,"a");
            map.put(1,"b");
            System.out.println(map);
            
            //数字先排序完,再字母排序
            Map<String,String> map1 = new TreeMap<String,String>();
            map1.put("32","a");
            map1.put("a","c");
            map1.put("ab", "ds");
            map1.put("11","1");
            map1.put("d","a");
            map1.put("1","b");
            System.out.println(map1);
            //剩下的方法就不演示了,可以参照上面的TreeSet方法差不多
            //定制排序
        }
    }
    View Code

    map集合的key是唯一的,如果对同一个key进行赋值,后面的会覆盖前面的key赋值。

    工具类Collections

     例子

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.List;
    
    public class Test11 {
        public static void main(String[] args) {
            List<String> list = new ArrayList<String>();
            list.add("b");
            list.add("cd");
            list.add("ca");
            list.add("d");
            list.add("1");
            
            System.out.println("list集合根据插入顺序排序: "+list);
            //Collections.reverse(list)集合排序反转
            Collections.reverse(list);
            System.out.println("颠倒排序: "+list);
            
            //Collections.shuffle(list)随机排序
            Collections.shuffle(list);
            System.out.println("随机排序:"+list);
            
            //Collections.sort(stus,new Student())字典升序排序
            Collections.sort(list);
            System.out.println("调用自然排序:"+list);
            
            //Collections.swap(list,arg1,arg2)交换list集合中的arg1和arg2的位置 ,元素交换
            Collections.swap(list, 0, 4);
            System.out.println("调换了0和4的位置后: "+list);
            
            //下面测试定制排序
            Student s1 = new Student(12,"si");
            Student s2 = new Student(21,"ga");
            Student s3 = new Student(54,"yi");
            Student s4 = new Student(11,"di");
            List<Student> stus = new ArrayList<Student>();
            stus.add(s1);
            stus.add(s2);
            stus.add(s3);
            stus.add(s4);
            //下面遍历并没有按照年龄进行排序
            //Student类明明实现了Comparator接口,但是TreeSet会根据年龄排序,为什么ArrayList就没有按照年龄排序呢
            //TreeSet会自动调用定制排序,但是ArrayList不会自动调用定制排序
            for(Student stu : stus) {
                System.out.println("age: "+stu.age+" name: "+stu.name);
            }
            
            //ArrayList调用定制排序需要使用Collections.sort(list,new XX())方法,才会调用定制排序进行年龄排序、
            //补充:Collections.sort(list)只会调用默认的自然排序,上面多个一个参数的才是调用定制排序
            Collections.sort(stus,new Student());
            System.out.println("--------------------");
            //下面遍历按照年龄进行排序,因为sort方法调用了定制排序
            for(Student stu : stus) {
                System.out.println("age: "+stu.age+" name: "+stu.name);
            }    
        }
    }
    
    //定制排序
    class Student implements Comparator<Student>{
        int age;
        String name;
        public Student() {}
        public Student(int age,String name) {
            this.age = age;
            this.name = name;
        }
        //根据年龄升序排序
        @Override
        public int compare(Student o1, Student o2) {
            if(o1.age > o2.age) {
                return 1;
            }
            else if(o1.age < o2.age) {
                return -1;
            }
            else {
                return 0;
            }
        }
    }
    View Code

    补充:为什么ArrayList要使用sort(List,Comparator)才会调用定制排序,TreeSet会自动调用定制排序。

    对比TreeSet和ArrayList不同代码区别:

    TreeSet:   Set<Person> set = new TreeSet<Person>(new Person());

    ArrayList:   List<Student> stus = new ArrayList<Student>();  Collections.sort(stus,new Student());

    Collection的查找/替换

     例子

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.List;
    
    public class Test12 {
        public static void main(String[] args) {
            List<String> list = new ArrayList<String>();
            list.add("b");
            list.add("ca");
            list.add("ca");
            list.add("d");
            list.add("b");
            list.add("1");
            
            //下面测试定制排序
            Student1 s1 = new Student1(12,"si");
            Student1 s2 = new Student1(21,"ga");
            Student1 s3 = new Student1(54,"yi");
            Student1 s4 = new Student1(11,"di");
            List<Student1> stus = new ArrayList<Student1>();
            stus.add(s1);
            stus.add(s2);
            stus.add(s3);
            stus.add(s4);
    
            //Collections.sort(stus,new Student())字典升序排序
            Collections.sort(list);
            System.out.println("调用自然排序:"+list);
            
            //Collections.max(list)获取集合中最大的元素
            String max = Collections.max(list);
            System.out.println("自然排序最大元素:"+max);
            
            //Collections.min(list)获取集合最小的元素
            String min = Collections.min(list);
            System.out.println("自然排序最小元素:"+min);
            
            
            //排序
            Collections.sort(stus,new Student1());
            System.out.println("--------------------");
            //下面遍历按照年龄进行排序,因为sort方法调用了定制排序
            for(Student1 stu : stus) {
                System.out.println("age: "+stu.age+" name: "+stu.name);
            }    
            //Collections.max(list,class);获取集合中定制类中最大的元素
            Student1 max2 = Collections.max(stus,new Student1());
            System.out.println("定制排序最大元素:"+max2.age+" "+max2.name);
            
            //Collections.min(list,class);获取集合中定制类中最小的元素
            Student1 min2 = Collections.min(stus,new Student1());
            System.out.println("定制排序的最小元素: "+min2.age+" "+min2.name);
            
            //Collections.frequency(集合, 元素)统计元素在集合中出现的次数
            Object arg = "b";
            int i = Collections.frequency(list,arg);
            System.out.println(arg+"元素出现的次数:"+i);
            
            //Collections.replaceAll(集合,旧元素,新元素);注意是替换全部,不是一个元素
            System.out.println("替换前的集合:"+list);
            Collections.replaceAll(list, "b","bb");
            System.out.println("替换后的集合:"+list);
        }
    }
    
    //定制排序
    class Student1 implements Comparator<Student1>{
        int age;
        String name;
        public Student1() {}
        public Student1(int age,String name) {
            this.age = age;
            this.name = name;
        }
        //根据年龄升序排序
        @Override
        public int compare(Student1 o1, Student1 o2) {
            if(o1.age > o2.age) {
                return 1;
            }
            else if(o1.age < o2.age) {
                return -1;
            }
            else {
                return 0;
            }
        }
    }
    View Code

    同步控制

     这里暂时不演示,等到多线程的时候。

  • 相关阅读:
    python通过scapy编写arp扫描器
    red hat重置密码
    浅谈跨域劫持
    python中的socket
    利用Python进行端口扫描
    自己搜罗了一些感觉蛮有意思的爬虫相关的网站
    与py2neo的第一次接触
    基本上所有的库的列表都在这里了,传送门~~~
    关于neo4j初入门(5)
    关于neo4j初入门(4)
  • 原文地址:https://www.cnblogs.com/unlasting/p/12663805.html
Copyright © 2011-2022 走看看