• 集合(下)


    7 Set 接口

    Set 接口表示一个唯一、无序的容器(和添加顺序无关)。

    7.1 Set 提供的方法

     1 public static void main(String[] args) {
     2         /**
     3          * 增:add/addAll
     4          * 删:clear/remove/removeAll/retainAll
     5          * 改:
     6          * 查:contains/containsAll
     7          * 遍历:iterator
     8          * 其他:size/isEmpty
     9          */
    10         
    11         Set<Integer> set = new HashSet<Integer>();
    12         // [1]添加
    13         // 无序
    14         set.add(10);
    15         set.add(3);
    16         set.add(20);
    17         set.add(0);
    18         // 不能添加重复元素
    19         boolean r = set.add(1);
    20         System.out.println(set);
    21         
    22         // 【2】删除
    23 //        set.remove(1);
    24 //        set.clear();
    25 //        System.out.println(set);
    26         
    27         // 【3】查看是否包含
    28         System.out.println(set.contains(1));
    29         
    30         // 【4】其他
    31         System.out.println(set.size());
    32         System.out.println(set.isEmpty());
    33 }

    7.2 Set 的遍历

     1 public static void main(String[] args) {
     2         
     3         Set<String> set = new HashSet<String>();
     4         set.add("banana");
     5         set.add("apple");
     6         set.add("coco");
     7         
     8         // 快速遍历
     9         for (String item : set) {
    10             System.out.println(item);
    11         }
    12         
    13         // 迭代器
    14         Iterator<String> it = set.iterator();
    15         while(it.hasNext()) {
    16             String item = it.next();
    17             System.out.println(item);
    18         }
    19 }

    8 HashSet

    HashSet 是 Set 接口的实现类,底层数据结构是哈希表。HashSet 是线程不安全的(不保证同步)。优点:添加、删除、查询效率高;缺点:无序

    8.1 添加自定义对象

    如果向 HashSet 中存储元素时,元素一定要实现hashCode方法和equals方法。

     1 public class Student {
     2     private String id;
     3     private String name;
     4     private int age;
     5 
     6     @Override
     7     public int hashCode() {
     8         final int prime = 31;
     9         int result = 1;
    10         result = prime * result + age;
    11         result = prime * result + ((id == null) ? 0 : id.hashCode());
    12         result = prime * result + ((name == null) ? 0 : name.hashCode());
    13         return result;
    14     }//当属性相同时,两个对象的 hashcode 相同,判断两个对象相等的必要不充分条件
    15 
    16     @Override
    17     public boolean equals(Object obj) {
    18         if (this == obj)
    19             return true;
    20         if (obj == null)
    21             return false;
    22         if (getClass() != obj.getClass())
    23             return false;
    24         Student other = (Student) obj;
    25         if (age != other.age)
    26             return false;
    27         if (id == null) {
    28             if (other.id != null)
    29                 return false;
    30         } else if (!id.equals(other.id))
    31             return false;
    32         if (name == null) {
    33             if (other.name != null)
    34                 return false;
    35         } else if (!name.equals(other.name))
    36             return false;
    37         return true;
    38     }//两个对象相等的充分必要条件
    39 
    40     @Override
    41     public String toString() {
    42         return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
    43     }
    44 
    45 }

    9 LinkedHashSet

    LinkedHashSet是Set接口的实现类,底层数据结构哈希表+链表。哈希表用于散列元素;链表用于维持添加顺序。如果要添加自定义对象元素,也需要重写 hashCode 和 equals 方法。

    10 TreeSet

    TreeSet 是Set接口的实现类,底层数据结构是二叉树。TreeSet 存储的数据按照一定的规则存储。存储规则让数据表现出自然顺序。

    10.1 工作原理

    添加一个新元素 t 的存储的步骤:

    1. 如果集合无元素,t 直接加入;如果集合有元素,t 和根节点比较;
    2. 如果 t 小于根节点;把 t 放到根节点的左子树上;重复1-3步骤
    3. t 大于根节点;把 t 放到根节点的右子树上;重复1-3步骤

    输出时按照一定的规则:左子树->根节点->右子树

    向TreeSet中添加元素时,一定要提供比较策略,否则会出现 ClassCastException。

    10.2 内部比较器

    当一个自定义对象实现Comparable并实现compareTo方法时,通过指定具体的比较策略,此时称为内部比较器。

     1 public class Student implements Comparable<Student>{
     2     private String id;
     3     private String name;
     4     private int age;
     5 
     6     @Override
     7     public String toString() {
     8         return "Student [id=" + id + ", name=" + name + ", age=" + age + "]";
     9     }
    10 
    11     @Override
    12     public int compareTo(Student o) {
    13         if(this.getAge()<o.getAge()) {
    14             return -1;
    15         }else if(this.getAge() == o.getAge()) {
    16             return 0;
    17         }else {
    18             return 1;
    19         }
    20     }
    21 
    22 }

    默认的比较器是按升序排列,所以只要重写的 compareTo 方法也是参数较大时返回 -1 即可实现升序排列。

    10.3 外部比较器

    当实际开发过程中不知道添加元素的源代码、无权修改别人的代码,此时可以使用外部比较器。TreeSet 接受一个指定比较策略的构造方法,这些比较策略的实现类必须实现 Compa-rator 接口。Comparator 位于java.util包中,定义了compare (o1,o2) 用于提供外部比较策略。推荐使用匿名内部类方法实现。

     1 public static void main(String[] args) {
     2         
     3         TreeSet<String> set2 = new TreeSet<String>(new Comparator<String>() {
     4 
     5             @Override
     6             public int compare(String o1, String o2) {
     7                 return o1.length() - o2.length();
     8             }
     9             
    10         });//比较规则是字符串长度的升序
    11         
    12         set2.add("banana");
    13         set2.add("coco");
    14         set2.add("apple");
    15         
    16         set2.add("apple");
    17         System.out.println(set2);
    18         
    19 }

    11 Map 接口

    Map接口称为键值对集合或者映射集合,其中的元素(entry)是以键值对(key-value)的形式存在。Map 容器接口中提供了增、删、改、查的方式对集合进行操作。Map接口中都是通过key来操作键值对,一般key是已知。通过key获取value。

    11.1 Map 常用方法

     1 public static void main(String[] args) {
     2         
     3         /**
     4          * 增:put/putAll
     5          * 删:clear/remove
     6          * 改:put
     7          * 查:get/containsKey/containsValue
     8          * 其他:isEmpty/size
     9          */
    10         
    11         Map<String, String> map = new HashMap<String,String>();
    12         
    13         // 【1】put
    14         map.put("A", "apple");
    15         map.put("B", "banana");
    16         map.put("C", "coco");
    17         
    18         // 【2】删除
    19         // map.clear();
    20         // smap.remove("A");
    21         
    22         // 【3】修改
    23         //map.put("A", "apple x");
    24         
    25         // 【4】查看
    26         String val = map.get("A");
    27         System.out.println(map.containsKey("D"));
    28         
    29         
    30         System.out.println(map);
    31 }

    11.2 Map 的遍历

    • 通过keySet() 返回map中键的set集合。
     1 public static void main(String[] args) {
     2 
     3         Map<String, String> map = new HashMap<String,String>();
     4         
     5         map.put("B", "banana");
     6         map.put("A", "apple");
     7         map.put("C", "coco");
     8         // map无序
     9         // 可以根据key的自然顺序 让map有序  => 一般用string作为key
    10         System.out.println(map);
    11         
    12         
    13         // 遍历
    14         Set<String> keys = map.keySet();
    15         for (String key : keys) {
    16             System.out.println(key+"=>"+map.get(key));
    17         }
    18         
    19         Iterator<String> it = keys.iterator();
    20         while(it.hasNext()) {
    21             String key = it.next();
    22             System.out.println(key+"=>"+map.get(key));
    23         }
    24 }
    • Map 中以键值对作为元素,键值对在map中称为entry,entrySet() 返回键值对的set集合,通过此集合遍历。
     1 public static void main(String[] args) {
     2 
     3         Map<String, String> map = new HashMap<String,String>();
     4         
     5         map.put("B", "banana");
     6         map.put("A", "apple");
     7         map.put("C", "coco");
     8         // map无序
     9         // 可以根据key的自然顺序 让map有序  => 一般用string作为key
    10         System.out.println(map);
    11         
    12         // entrySet
    13         Set<Entry<String, String>> entrySet = map.entrySet();
    14         for (Entry<String, String> entry : entrySet) {
    15             System.out.println(entry.getKey()+"=>"+entry.getValue());
    16         }
    17         
    18         Iterator<Entry<String, String>> it2 = entrySet.iterator();
    19         while(it2.hasNext()) {
    20             Entry<String, String> entry = it2.next();
    21             System.out.println(entry.getKey()+"=>"+entry.getValue());
    22         }
    23 }

    12 HashMap

    HashMap 是 Map 的实现类,key 以 HashSet 存储。HashMap 线程不安全,jdk1.2;Hashtable 是 HashMap 的线程安全版本,jdk1.0。向HashMap中存储元素时,key一定要实现 hashCode 和 equals。

    13 LinkedHashMap

    LinkedHashMap 是 Map 接口的实现类,key 以 LinkedHashSet 存储。哈希表散列key,链表维持key的添加顺序。

    14 TreeMap

    TreeMap 是 Map 的实现类,key 以 TreeSet 存储。key 如 TreeSet 一样要具有比较器。

    15 总结

  • 相关阅读:
    3.16
    3.8
    3.7
    3.6
    3.5
    3.3
    3.2
    《机器学习十讲》学习报告一
    机器学习-集成算法
    机器学习-基于核的算法
  • 原文地址:https://www.cnblogs.com/carlosouyang/p/10815882.html
Copyright © 2020-2023  润新知