zoukankan      html  css  js  c++  java
  • java之集合(Set、List、Map)

    java集合类存放于java,uti包中,是一个用于存放对象的容器。

    • 集合只能存放对象,比如存入的是int型数据1,那么它会自动转换成Integer包装类后再存入;
    • 集合存放的是多个对象的引用,对象本身还是放在堆内存中;
    • 集合可以存放不同类型、不限数量的数据类型;

    java集合可以分为Set、Map和List三大体系。

    • Set:无序、不可重复的集合;
    • List:有序、可重复的集合;
    • Map:具有映射关系的集合;

    在JDK5之后,增加了泛型,java集合可以记住容器中对象的数据类型。


    一、HashSet

    HashSet是Set接口的典型实现,大多数时候使用Set集合时都会使用这个实现类。我们大多数时候说的Set集合指的就是HashSet。

    HashSet是哈希算法来存储集合的元素,因此具有很好的存取和查找的性能。

    HashSet具有以下特点:

    • 不能保证元素的排列顺序;
    • 不可重复;
    • HashSet不是线程安全的;
    • 集合元素可以是null;

    当向HashSet中存入一个元素时,HashSet会调用该对象的hashCode()方法来得到该对象的hashCode值,然后根据hashCode的值决定该对象在HashSet中存储的位置。如果两个元素的equals()方法返回true,但它们的hashCode()返回值不相等,HashSet会将它们存储在不同的位置,但依然可以添加成功。

    HashSet--实现Set接口,Set接口继承Collection接口。

    package collections;
    
    import java.util.Set;
    import java.util.HashSet;
    import java.util.Iterator;
    
    public class Test {
        public static void main(String[] args) {
            Set set = new HashSet();
            //添加一个对象
            set.add(1);
            set.add("a");
            System.out.println(set);
            //删除一个对象
            set.remove(1);
            System.out.println(set);
            //判断是否包含某个对象
            System.out.println(set.contains("a"));
            //清空集合
            set.clear();
            set.add("a");
            set.add("b");
            set.add("c");
            set.add("d");
            //可以存放null
            set.add(null);
            //使用迭代器遍历集合
            Iterator it = set.iterator();
            while(it.hasNext()) {
                System.out.println(it.next());
            }
            //for each迭代集合
            //将set中的每一个值取出来赋值给obj
            for(Object obj:set) {
                System.out.println(obj);
            }
            //取得set的长度
            System.out.println(set.size());
            //存放指定数据类型(string)的对象
            Set<String> stringSet = new HashSet<String>();
            stringSet.add("a");
            stringSet.add("b");
            for(String str:stringSet){
                System.out.println(str);
            }
        }
    }

    二、TreeSet

    TreeSet是SortedSet的接口实现类,其主要关系如下:TreeSet类实现NavigableSet接口,NavigableSet接口继承SortedSet接口,SortedSet继承Set接口,Set接口继承Collection接口。TreeSet可以确保集合元素处于排序状态。TreeSet支持两种排序方法:自然排序和定制排序,默认情况下,TreeSet采用自然排序。

    自然排序:TreeSet会调用结合元素的compareTo(Object obj)方法来比较元素之间的大小关系,然后将元素按升序排列。如果this>obj,返回1,如果this<obj,返回-1,如果this=obj,返回0,则认为两个对象相等。注意:必须放入同种类型的对象(默认会进行排序),否则可能发生类型转换异常,可以使用泛型来进行限制。

    package collections;
    
    import java.util.Set;
    import java.util.TreeSet;
    
    public class Test2 {
        public static void main(String[] args) {
            Set<Integer> set = new TreeSet<Integer>();
            set.add(5);
            set.add(2);
            set.add(4);
            set.add(3);
            System.out.println(set);
            set.remove(4);
            System.out.println(set);
            System.out.println(set.contains(3));
        }
        
    }

    里面的元素是有序的,即[2,3,4,5]。

    我们也可以自定义排列规则:

    package collections;
    
    import java.util.Comparator;
    import java.util.Set;
    import java.util.TreeSet;
    
    public class Test2 {
        public static void main(String[] args) {
            Set<Person> set = new TreeSet<Person>(new Person());
            Person p1 = new Person("tom",21);
            Person p2 = new Person("mike",18);
            Person p3 = new Person("bob",43);
            set.add(p1);
            set.add(p2);
            set.add(p3);
            for(Person p:set) {
                System.out.println("名字:"+p.name+" "+"年龄:"+p.age);
            }
        }
        
    }
    class Person implements Comparator<Person>{
        String name;
        int age;
        public Person() {}
        public Person(String name,int age) {
            this.name = name;
            this.age = age;
        }
        @Override
        public int compare(Person p1,Person p2) {
            if (p1.age>p2.age){
                return 1;
            }else if(p1.age<p2.age) {
                return -1;
            }else {
                return 0;
            }
        }
    }

    输出:

    名字:mike 年龄:18
    名字:tom 年龄:21
    名字:bob 年龄:43

    可以发现,确实是按照年龄进行排序的,若想按照降序来排序,只需要将Person中的返回1和-1进行交换即可。


    三、List与ArrayList

    List代表一个有序、且可重复的集合,集合中的每个元素都有其相对应的顺序索引。

    List允许使用重复元素,可以通过索引来访问指定位置的集合元素。

    List默认按元素的添加顺序进行索引的设置。

    List集合里添加了一些根据索引来操作集合元素的方法。

    ArrayList类实现了List接口,List接口继承了Collection接口。

    package collections;
    
    import java.util.ArrayList;
    import java.util.List;
    
    public class Test3 {
        public static void main(String[] args) {
            List<String> list1 = new ArrayList<String>();
            //按顺序插入元素
            list1.add("a");
            list1.add("c");        
            list1.add("b");
            System.out.println(list1);
            //在指定的索引插入元素
            list1.add(1,"d");
            List<String> list2 = new ArrayList<String>();
            list2.add("123");
            list2.add("456");
            //添加另一个列表结合
            list1.addAll(2,list2);
            System.out.println(list1);
            //根据索引获取元素
            System.out.println(list1.get(1));
            //获取元素第一次出现的索引
            System.out.println(list1.indexOf("d"));
            //获取元素最后一次出现的索引
            System.out.println(list1.lastIndexOf("d"));
            //根据索引删除元素
            list1.remove(1);
            //根据索引修改元素
            list1.set(2,"66");
            System.out.println(list1);
            //根据区间获取元素,即索引为2,3的元素
            List<String> subList = list1.subList(2, 4);
            System.out.println(subList);
            //集合的长度
            System.out.println(list1.size());
        }
    }

    ArrayList和Vector都是List接口的典型实现:

    区别:

    • Vector是一个古老的集合,通常建议使用ArrayList;
    • ArrayList是线程不安全的,而Vector是线程安全的;
    • 即使为保证List集合线程安全,也不建议使用Vector;

    四、Map

    Map用于保存具有映射关系的数据,因此Map集合里保存着两组值,一组用于保存Map里的key,一组用于保存Map里面的value。

    Map中的key和value都可以是任意引用数据类型的数据。

    Map中key不允许重复,即同一个Map对象的任何两个Key通过equals方法比较都会返回false。

    key和value之间存在单向一对一关系,即通过指定的key总能找到唯一的,确定的value。

    package collections;
    
    import java.util.HashMap;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;
    
    public class Test4 {
        public static void main(String[] args) {
            Map<Integer, String> map = new HashMap<Integer,String>();
            //添加一个键值对
            map.put(1, "b");
            map.put(2, "a");
            map.put(3, "c");
            System.out.println(map);
            //通过键获取值
            System.out.println(map.get(1));
            //通过键删除某条键值对数据
            map.remove(1);
            //大小
            System.out.println(map.size());
            //是否包含键为2的数据
            System.out.println(map.containsKey(2));
            //是否包含值为"c"的数据
            System.out.println(map.containsValue("c"));
            //遍历Map集合
            //获取key的集合
            map.keySet();
            //获取value的集合
            map.values();
            //通过key来遍历
            Set<Integer> keys = map.keySet();
            for(Integer key:keys) {
                System.out.println("key:"+key+",val:"+map.get(key));
            }
            //通过map.entrySet(),Entry代表键值对对象
            Set<Entry<Integer,String>> entrys = map.entrySet();
            for(Entry<Integer,String> entry:entrys) {
                System.out.println("key="+entry.getKey()+","+"value="+entry.getValue());
            } 
        }
    }

    HashMap和Hashtable是Mao接口的两个实现类。

    区别:

    • Hashtable是一个古老的Map实现类,不建议使用;
    • Hashtable是一个线程安全的Map实现,但是HashMap是线程不安全的;
    • Hashtable不允许使用null作为key和value的值,而HashMap可以;

    与HashSet集合不能保证元素的顺序一样,Hashtable和HashMap也不能保证其中key-value对的顺序。

    Hashtable和HashMap判断两个key相同的标准是:两个key通过equals方法返回true,hashCode也相等。

    Hashtable和HashMap判断两个value相同的标准是:两个value通过equals方法返回true


    五、TreeMap

    TreeMap存储键值对时,需要根据key对键值对进行排序,TreeMap可以保证所有的键值对处于有序状态。

    自然排序:TreeMap所有的key必须实现Comparable接口,而且所有的Key应该是同一个类的对象,否则会抛出异常;

    定制排序:创建TreeMap时,传入一个Comparator对象,该对象负责对TreeMap的所有Key进行排序,此时不需要Map的key实现Comparable接口;

            Map<Integer, String> map2 = new TreeMap<Integer,String>();
            map2.put(2,"b");
            map2.put(1,"a");
            map2.put(3,"c");
            System.out.println(map2);

    输出:

    {1=a, 2=b, 3=c}

  • 相关阅读:
    lxml库之xpath的使用
    简单使用三层架构完成学生管理系统之增加功能
    mybatis——逆向工程以及案例
    Java——mybatis(使用mybatis对mysql数据库进行增删改查的操作)
    linux运维、架构之路-K8s故障排查
    linux运维、架构之路-管理K8s组件日志
    linux运维、架构之路-k8s监控集群资源利用率
    linux运维、架构之路-k8s部署redis
    linux运维、架构之路-kubernetes集群维护
    linux运维、架构之路-kubeadm快速部署kubernetes集群
  • 原文地址:https://www.cnblogs.com/xiximayou/p/12060402.html
Copyright © 2011-2022 走看看