zoukankan      html  css  js  c++  java
  • Java SE入门(十五)——Set和Map集合

    iwehdio的博客园:https://www.cnblogs.com/iwehdio/

    1、Set接口

    • Set 集合特点:

      1. 无序,存储和读取的顺序有可能不一样。
      2. 不允许重复,要求元素是唯一的。
      3. 没有索引。
    • HashSet :Set 的一个子类实现。

      • 使用 HashSet存储自定义对象并遍历。

      • 流程:

        1. 创建集合对象。
        2. 创建元素对象。
        3. 添加元素对象。
        4. 遍历集合方法。
          • 转型为数组。
          • 迭代器。
          • 增强 for 。
      • 例:

        HashSet<Student> hs = new HashSet<Student>();
        Student s = new Student("A", 12);
        hs.add(s);
        for(Student s : hs){
            System.out.println(s);
        }
        
    • HashSet 的 add() 方法会添加重复元素的原因:

      • 该方法首先比较的是 hash 值比较,如果不一样则认为没有重复,添加。

      • 如果 hash 值一样,则再比较地址值或使用 equals 方法比较。

      • 如果没有重写 hashCode() 方法,重复元素的 hash 值就是地址值,认为不重复。

      • 重写 hashCode() 和 equals() 方法:

        • 重写 equals() 方法:比较对象的每个元素是否相等,

          @Override
          public boolean equals(Object obj){
              Student s = (Student)obj;
              if(!this.name.equals(s.name)){
                  return false;
              }
              if(this.age != s.age){
                  return false;
              }
              return true;
          }
          
        • 重写 hashCode() 方法:永远返回一个相同的值。

          @Override
          public int hashCode(){
              return 1;
          }
          
    • 优化重写的 hashCode() 方法:

      • 对于完全不同的成员变量,返回不同的值。

      • 让 hashCode() 的返回值与成员变量有关,例如返回所有的成员变量之和。基本数据类型直接相加,引用数据类型获取 hashCode() 方法返回后再相加(不包括bool类型)。

      • 例:

        @Override
        public int hashCode(){
            //调用 String 的 hashCode() 方法
            return age + name.hashCode();
        }
        
    • 优化重写的 equals() 方法:

      • 先比较地址值。
      • .getClass()方法,判断是否属于同一个类。
    • 自动生成:右键 > source > Generate hashCode() and equals() 。

    • Collection :集合体系的最顶层,包含了集合体系的共性。

    • Collections :是一个工具类,方法就是用于操作 Collection。

      • static int binarySearch(List list, Object key):使用二分查找,查找指定元素。

        List<Integer> list = new ArrayList<Integer>();
        /*添加元素*/
        int index = Collections.binarySearch(list, 4);
        
      • static void copy(List dext, Lit src):把源列表中的数组覆盖到目标列表(目标列表长度要大于等于源列表)。

      • static void fill(List list, Object obj):使用指定对象填充指定列表的所有元素。

      • static void reverse(List list):反转列表。

      • static void shuffle(List list):列表随机置换(顺序打乱。)

      • static void sort(List list):按自然顺序排序。

      • static void swap(List list,int i,int j):互换列表中两个索引的数据。

    • 模拟发牌:

      ArrayList<String> box = new ArrayList<String>();
      //创建牌池		
      String[] arr = {"B", "R", "F", "M"};
      String[] arr2 = {"1","2","3","4","5","6","7","8","9","10","11","12","13"};
      for(int i=0;i<arr.length;i++){
          for(int j=0;j<arr2.length;j++){
              box.add(arr[i]+arr2[j]);
          }
      }
      box.add("Big");
      box.add("Small");
      //打乱
      Collections.shuffle(box);
      System.out.println(box);
      //创建容器
      ArrayList<String> Q = new ArrayList<String>();
      ArrayList<String> W = new ArrayList<String>();
      ArrayList<String> E = new ArrayList<String>();
      //发牌
      for(int i=0;i<box.size()-3;i++){
          switch(i%3){
              case 0:
                  Q.add(box.get(i));
                  break;
              case 1:
                  W.add(box.get(i));
                  break;
              case 2:
                  E.add(box.get(i));
                  break;
          }
      }
      System.out.println(Q);
      System.out.println(W);
      System.out.println(E);
      for(int i=box.size()-3;i<box.size();i++){
          System.out.println(box.get(i));
      }
      

    2、Map接口

    体现有对应关系的数据,是一个将键映射到值的对象。

    • 不能包含重复的键;每个键最多映射一个值。

    • Map 是一个双列集合,不是 Collection 的子接口,是另一种顶层结构。

    • HashMap :Map的一个子类实现。

      • V put(K key, V value):将 key 映射到 value,如果 key 存在则覆盖 value 并返回被覆盖的原 value,实现添加和修改。
      • boolean containsKey(Object key):判断指定的 key 是否存在。
      • boolean containsValue(Object Value):判断指定的 value 是否存在。
      • boolean isEmpty():判断是否为空。
      • void clear():清空所有键值对。
      • V remove(Object key):按输入的键删除键值对,返回 key 对应的值。没有删除成功则返回 null 。
      • int size():返回键值对的个数。
      • V get(Object key):按输入的键获取对应的值。
    • 创建 Map<K,V> 对象,需要给定 key 和 value 的泛型。

      Map<String,String> map = new HashMap<String,String>();
      
    • Set<K> keySet():获取所有的键。返回类型为 Set ,泛型为 key 的类型 K 。

    • Collection<V> values():获取所有的值。返回类型为 Collection ,泛型为 value 的类型 V 。

    • Map 的遍历方式:

      1. 首先获取所有的键;遍历所有的键,获取所有键对应的值。

        Map<String,String> map = new HashMap<String,String>();
        map.put("key1","value1");
        map.put("key2","value2");
        
        Set<String> keys = mao.keySet();
        for(String key : keys){
            String value = map.get(key);
            System.out.println(key + ": " + value);
        }
        
      2. 通过创建一个类,将每个键值对都通过这个类实例化为一个对象。

      • Map 中有一个这样的方法:Set<Map.Entry<K,V>> entrySet()
      • 返回类型是 Set ,元素类型为 Map.entry 对象,泛型为 key 和 value 的泛型。
      • 每个 Map.entry 对象就是一个键值对,可以通过 .getKey().getValue() 方法获取键和值。
      Map<String,String> map = new HashMap<String,String>();
      map.put("key1","value1");
      map.put("key2","value2");
      
      Set<Map.entry<String,String>> entrys = map.entrySet();
      for(Map.Entry<String,String> entry : entrys){
          String key = entry.getKey();
          String value = entry.getValue();
          System.out.println(key + ": " + value);
      }
      
    • 使用 HashMap 存储数据并遍历(key为自定义对象时):

      HashMap<Student,String> hm =new HashMap<Student,String>();
      Student s = new Student("A", 12);
      
      hm.put(s,"value");
      // 遍历方法1
      Set<Student> keys = hm.keySet();
      for(Student key : keys){
          String value = hm.get(key);
      }
      // 遍历方法2
      Set<Map.Entry<Student,String>> entrys = hm.entrySet();
      for(Map.Entry<Student,String> entry : entrys){
          String key = entry.getKey();
          String value = entry.getValue();
      }
      
    • 这样还是会添加重复的 Student 对象 :需要 Student 类重写 HashCode() 和 equals() 方法。


    iwehdio的博客园:https://www.cnblogs.com/iwehdio/
  • 相关阅读:
    ACM成长之路
    洛谷P1047 校门外的树
    洛谷P1046 陶陶摘苹果
    2017 ACM-ICPC 亚洲区(南宁赛区)网络赛 F题
    图论:POJ2186-Popular Cows (求强连通分量)
    DFS:POJ1562-Oil Deposits(求连通块个数)
    DFS:POJ3620-Avoid The Lakes(求最基本的联通块)
    map函数的应用:UVa156-Ananagrams
    set的应用:UVa10815-Andy's First Dictionary
    水题:UVa253-Cube painting
  • 原文地址:https://www.cnblogs.com/iwehdio/p/12242334.html
Copyright © 2011-2022 走看看