Java中的集合(下)

一,Map集合

1.概述:
  • 该集合存储键值对。一次添加一对,而且要保证键的唯一性。
  • 嵌套类摘要 static interface Map.Entry
2.常用方法:
2.1 添加
  • value put( key,value ):返回前一个和key关联的值,如果没有返回null。

    说明:添加元素,如果出现相同的键,那么后添加的值会覆盖原有键对应的值,put方法会返回被覆盖的值

2.2 删除
  • void clear():清空map集合。
  • value remove(Object key):根据指定的key删除这个键值对。
2.3 判断
  • boolean containsKey(key);
  • boolean containsValue(value);
  • boolean isEmpty();
2.4 获取
  • value get(key):通过键获取值,如果没有该键返回null。当然可以通过返回null,来判断是否包含指定键。
  • int size():获取键值对个数。
  • Collection values() 返回此映射中包含的值的 Collection 视图。
  • Set keySet() 返回此映射中包含的键的 Set 视图。
  • Set
3. map集合的两种取出方式;
3.1 第一种:keySet()方法
  • 原理:
    • 通过keySet方法将map中所有的键存入到Set集合。因为set具备迭代器,所以可以迭代方式取出所有的键,再根据get方法,获取每一个键对应的值。
  • 代码示例:
    import java.util.*;
    class MapDemo {
        public static void main(String[] args) {
            Map<String,String> map=new HashMap<String,String>();
            map.put("001","A1");
            map.put("003","C3");
            map.put("002","B2");
            map.put("004","D4");    

            //1.先获取map集合的所有键的Set集合,keySet();
            Set<String> keySet=map.keySet();

            //2.有了Set集合,就可以获取其迭代器。
            Iterator<String> it = keySet.iterator();

            while (it.hasNext()) {
                String key=it.next();
                //3.有了键值可以通过map集合的get方法获取对应的值。
                String value=map.get(key);
                System.out.println("key:"+key+"---value:"+value);
            }
    }
3.2 第二种:内部接口 Map.Entry

Entry是Map接口里面的一个内部接口,用于封装key- value,有3个方法:

a. Object getKey(); 返回Entry里包含的key值

b. Object getValue(); 返回Entry里包含的value值

c. Object setValue(Object value); 设置Entry里包含的value值,并返回新设置的value值;

  • 原理:

    • 通过entrySet()方法,将键和值的映射关系(映射关系的类型就是Map.Entry类型)作为对象存储到了Set集合中,调用Set的iterator方法,此时每个Iterator对象是Map.Entry对象,对Map.Entry分离出key - value。
  • 代码示例(接):

    Set<Map.Entry<String,String>> es = map.entrySet();

    Iterator<Map.Entry<String,String>> it = es.iterator();

    while (it.hasNext()){
        Map.Entry<String,String> me=it.next();
        String key = me.getKey();
        String value = me.getValue();
        System.out.println(key+"::"+value);
    }
3.3 第三种:values()
  • 原理:通过values方法将map集合的值存入Collection集合,再使用迭代器获取
  • 代码示例(接):
    Collection<String> values = map.values();

    Iterator<String> it = values.iterator();
    while(it.hasNext()){
        System. out.println(it.next());
    }
4. HashMap
4.1 特点:
  • 判断键的唯一性的方式:以元素的Hashcode值和对象的equals方法判断键的唯一性。

  • 代码示例:

    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;

    /*
     * 将学生对象(年龄和姓名)和学生的归属地通过键与值存储到map集合中
    * 注意:姓名和年龄相同的视为同一个学生。
    * 保证学生的唯一性。
    */

    public class HashMapDemo {
        public static void main(String[] args) {
            HashMap<Student, String> hs = new HashMap<Student, String>();
            System.out.println("HashMap集合存储元素调用haseCode和equals过程:");
            hs.put(new Student("lishi01", 21), "beijing");

            // 先判断hashCode的值,相等,再判断equals是否相等,相等则key重复,value将被会覆盖,即"beijing"被"tianjin"覆盖
            hs.put(new Student("lishi01", 21), "tianjin");
            hs.put(new Student("lishi02", 22), "shanghai");
            hs.put(new Student("lishi03", 23), "nanjing");

            //先判断hashCode的值,不相等,则key不同,向集合中存入该元素
            hs.put(new Student("lishi01", 24), "wuhan");

            System.out.println("------------------");
            Iterator<Map.Entry<Student, String>> its = hs.entrySet().iterator();
            while (its.hasNext()) {
                Map.Entry<Student, String> es = its.next();
                Student stu = es.getKey();
                String addr = es.getValue();

                System.out.println(stu + "......" + addr);
            }
        }
    }

    class Student {
        private String name;
        private int age;

        Student(String name, int age) {
            this.name = name;
            this.age = age;
        }

        @Override
        public int hashCode() {
            //输出调用该方法对象的name
            System.out.println(this.name+"...hashCode");
            final int prime = 31;
            int result = 1;
            result = prime * result + age;
            result = prime * result + ((name == null) ? 0 : name.hashCode());
            return result;
        }

        @Override
        public boolean equals(Object obj) {
            //输出调用该方法的对象与传入对象相比较的name
            System.out.println(this.name+"...equals..."+((Student) obj).getName()); 
            if (this == obj)
                return true;
            if (obj == null)
                return false;
            if (getClass() != obj.getClass())
                return false;
            Student other = (Student) obj;
            if (age != other.age)
                return false;
            if (name == null) {
                if (other.name != null)
                    return false;
            } else if (!name.equals(other.name))
                return false;
            return true;
        }

        public String getName() {
            return name;
        }

        public int getAge() {
            return age;
        }

        // 转换成字符串
        public String toString() {
            return name + ":" + age;
        }
    }
  • 运行结果:

  • 如果希望输入的键值对集合按照跟原来存入的顺序一致,就使用LInkedHashMap

5. TreeMap:
5.1 特点:
  • 给map集合中的键按自然顺序进行排序
  • 判断键的唯一性的方式:就是根据保证元素唯一性的依据比较方法(实现Comparable接口中根据覆盖的compareTo方法返回值,实现Comparator接口中根据覆盖的compare方法)的返回结果是否是0,是0,就是相同元素,不存。
5.2 键值自定义排序:
  • 两种方法,与TreeSet中的自定义一样
  • 代码示例:
    /*
    *需求:对学生对象的年龄进行升序排列。
    *因为数据是可以以键值对形式存在的。
    *所以要使用可以排序的Map集合:TreeMap.
    */
    import java.util.Comparator;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.TreeMap;

    public class TreeMapDemo {
        public static void main(String[] args) {
            TreeMap<Student, String> tm = new TreeMap<Student, String>(new StuNameComparator());
            System.out.println("TreeMap集合储存元素,调用compare方法过程:");

            tm.put(new Student("lishi02", 22), "shanghai");
            tm.put(new Student("lishi01", 21), "beijing");

            // 1.调用compare方法,先与集合中已存在的"lishi02"比较:key不同;
            // 2.再与"lishi01"比较:name相同;然后再比较age:相同;则key相同;
            // 3.将value进行覆盖:"beijing"被"tianjin"覆盖
            tm.put(new Student("lishi01", 21), "tianjin");
            tm.put(new Student("lishi03", 23), "nanjing");

            // key不同,将不会覆盖
            tm.put(new Student("lishi01", 24), "wuhan");
            System.out.println("--------------------");
            Iterator<Map.Entry<Student, String>> it = tm.entrySet().iterator();
            while (it.hasNext()) {
                Map.Entry<Student, String> me = it.next();
                Student stu = me.getKey();
                String addr = me.getValue();
                System.out.println(stu + "..." + addr);
            }
        }
    }

    // 采用第二种方式,进行键值排序:定义一个类实现Comparator接口,覆盖Compare方法
    class StuNameComparator implements Comparator<Student> {
        public int compare(Student s1, Student s2) {
            System.out.println(s1.getName() + "..." + s2.getName());
            int num = s1.getName().compareTo(s2.getName());
            if (num == 0)
                return new Integer(s1.getAge()).compareTo(new Integer(s2.getAge()));
            return num;
        }
    }

    class Student {
        private String name;
        private int age;

        Student(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String getName() {
            return name;
        }

        public int getAge() {
            return age;
        }

        // 转换成字符串
        public String toString() {
            return name + ":" + age;
        }
    }

运行结果:

二,Collections工具类:

Collectons:是集合框架的工具类,位于java.util 包,完全由在 collection 上进行操作或返回,里面的方法都是静态的。

1. Collections和Collection的区别
  • Collection是集合框架中的一个顶层接口,它里面定义了单列集合的共性方法。

    • 它有两个常用的子接口(List:对元素都有定义索引,有序的,可以重复元素;Set:不可以重复元素。无序。)
  • Collections是集合框架中的一个工具类。该类中的方法都是静态的

    • 提供的方法中有可以对list集合进行排序,二分查找等方法。
    • 通常常用的集合都是线程不安全的。因为要提高效率。
    • 如果多线程操作这些集合时,可以通过该工具类中的同步方法,将线程不安全的集合,转换成安全的。
2. 常用方法:
2.1 排序:
  • static <T extends Comparable<? super T>> void sort(List<T> list):根据元素的自然顺序 对指定列表按升序进行排序。
  • static <T> void **sort**(List<T> list, Comparator<? super T> c)根据指定比较器产生的顺序对指定列表进行排序。
2.2 获取:
  • static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll):根据元素的自然顺序,返回给定 collection 的最大(最小为min)元素。
  • static <T> T **max**(Collection<? extends T> coll, Comparator<? super T> comp):根据指定比较器产生的顺序,返回给定 collection 的最大(最小为min)元素。
  • static <T> int binarySearch(List<? extends Comparable<? super T>> list, T key):使用二分搜索法搜索指定列表,以获得指定对象。如果搜索键包含在列表中,则返回搜索键的索引;否则返回 (-(插入点) - 1)。
  • static <T> int binarySearch(List<? extends T> list, T key, Comparator<? super T> c)使用二分搜索法搜索指定列表,以获得指定对象。
2.3 修改
  • static void swap(List<?> list, int i, int j)在指定列表的指定位置处交换元素。
  • static <T> boolean **replaceAll**(List<T> list, T oldVal, T newVal)使用另一个值替换列表中出现的所有某一指定值。
  • static <T> void **fill**(List<? super T> list, T obj) 使用指定元素替换指定列表中的所有元素。
  • static void shuffle(List<?> list)使用默认随机源对指定列表进行置换。
2.4 反转方法
  • static void reverse(List<?> list) 反转指定列表中元素的顺序。
  • static <T> Comparator<T> reverseOrder() 返回一个比较器,它强行逆转实现了 Comparable 接口的对象 collection 的自然顺序。
  • static <T> Comparator<T> reverseOrder(Comparator<T> cmp) 返回一个比较器,它强行逆转指定比较器的顺序。
2. 代码示例:
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.List;

    /*
     * 需求:分别按自然顺序进行二分法查找,并打印索引,
     * 按字符串长度进行二分法查找,并打印索引,并演示
     * Collections的sort方法和binarySearch方法的实现过程。
     */

    class CollectionsDemo {
        public static void main(String[] args) {
            binarySearchDemo();
        }

        public static void binarySearchDemo() {
            List<String> list = new ArrayList<String>();

            list.add("abcd");
            list.add("aaa");
            list.add("cc");
            list.add("kkk");
            list.add("qq");
            list.add("z");

            System.out.println("按自然顺序进行二分法查找,并打印索引结果示例:");

            // 按自然顺序排序,并打印
            Collections.sort(list);

            System.out.println(list);

            // 按自然顺序进行二分法查找,并打印索引
            // int index =Collections.binarySearch(list,"cc");//
            int index = halfSearch(list, "ccc");
            System.out.println("index=" + index);

            System.out.println("");

            System.out.println("按字符串长度进行二分法查找,并打印索引结果示例:");

            // 按字符串长度排序,并打印
            //Collections.sort(list, new StrLenComparator());//根据指定比较器产生的顺序(字符串长度)对指定列表进行排序

            //自定义按字符串长度排序方法
            mySort(list,new StrLenComparator());
            System.out.println(list);

            // 按指定的比较器(按字符串长度)对列表进行二分法查找,并打印索引
            // int lenIndex =Collections.binarySearch(list,"cc",new StrLenComparator());

            //自定义按字符串长度进行二分法查找,并打印索引
            int lenIndex = halfSearch2(list, "ccc", new StrLenComparator());
            System.out.println("lenIndex=" + lenIndex);
        }

        public static <T> void mySort(List<T> list,Comparator<? super T> comp) {
            for(int i = 0; i < list.size() - 1; i++){
                for(int j = i + 1; j < list.size(); j++){
                    if(comp.compare(list.get(i),list.get(j))>0){
                        Collections. swap(list ,i,j);
                    }
                }
            }
        }

        public static int halfSearch(List<String> list, String key) {
            int max, min, mid;
            max = list.size() - 1;
            min = 0;
            while (min <= max) {
                mid = (min + max) >> 1;
                String str = list.get(mid);

                int num = str.compareTo(key);
                if (num > 0)
                    max = mid - 1;
                else if (num < 0)
                    min = mid + 1;
                else
                    return mid;
            }
            return -min - 1;    //模拟返回值:-(插入点) - 1
        }

        public static int halfSearch2(List<String> list, String key,
                Comparator<String> cmp) {
            int max, min, mid;
            max = list.size() - 1;
            min = 0;
            while (min <= max) {
                mid = (min + max) >> 1;
                String str = list.get(mid);
                int num = cmp.compare(str, key);
                if (num > 0)
                    max = mid - 1;
                else if (num < 0)
                    min = mid + 1;
                else
                    return mid;
            }
            return -min - 1;    //模拟返回值:-(插入点) - 1
        }
    }

    // 采用比较器,根据字符串长度进行排序,若长度相等,则安自然排序
    class StrLenComparator implements Comparator<String> {
        public int compare(String s1, String s2) {
            if (s1.length() > s2.length())
                return 1;
            if (s1.length() < s2.length())
                return -1;
            return s1.compareTo(s2);
        }
    }

运行结果:

三,Arrays工具类:

Arrays是集合框架中的工具类,里面的方法都是静态的,包含用来操作数组(比如排序和搜索)的各种方法。此类还包含一个允许将数组作为列表来查看的静态工厂。

1. 数组和集合的互转:
1.1 数组转集合;
  • static List asList(T… a) 返回一个受指定数组支持的固定大小的列表。 可以使用集合的方法操作数组。

    注意:数组的长度是固定的,所以对于结合的增删方法是不可以使用的,否则,会发生UnsupportedOperationException。
    • 如果数组中的元素是对象,那么转成集合时,直接将数组中的元素作为集合中的元素进行集合存储。
    • 如果数组中的元素是基本类型数值,那么会将该数组作为集合中的元素进行存储。

      int[] arr1 = {31,11,51,61};
      List< int[]> list1 = Arrays.asList(arr1);
      System.out.println(list1); //[[I@19bb25a]
      Integer[] arr2 = {31,11,51,61};
      List list2 = Arrays.asList(arr2);
      System.out.println(list2); //[31, 11, 51, 61]
1.2 集合转数组:
  • 使用Collection接口中的toArray方法,可以对集合中的元素操作的方法进行限定,不允许对其进行增删
  • 需要传入一个指定类型的数组
  • 长度定义:
    • 如果长度小于集合的size,那么该方法会创建一个同类型并和集合相同的size的数组。
    • 如果长度大于集合的size,那么该方法就会使用指定的数组,存储集合中的元素,其他位置默认为null。
  • 所以建议,最后长度就指定为,集合的size。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值