• 集合Collection和Map


    Java集合可分为 Collection 和 Map 两种体系

    1、Collection接口:单列数据,定义了存取一组对象的方法的集合

    • List:元素有序、可重复的集合
    • Set:元素无序、不可重复的集合

    2、Map接口:双列数据,保存具有映射关系 ”key-value对“ 的集合


    一、Collection接口

    说明:

    • Collection 接口是 List、Set 和 Queue 接口的父接口,该接口里定义的方法 既可用于操作 Set 集合,也可用于操作 List 和 Queue 集合。
    • JDK不提供此接口的任何直接实现,而是提供更具体的子接口(如:Set和List)
      实现。
    • 在 Java5 之前,Java 集合会丢失容器中所有对象的数据类型,把所有对象都 当成 Object 类型处理;从 JDK 5.0 增加了泛型以后,Java 集合可以记住容器中对象的数据类型。

    1、常用方法

    import org.junit.Test;
    
    import java.util.*;
    
    /**
     * 要求:
     * 想Collection接口的实现类的对象中添加数据obj时,要求obj所在类要重写equals()
     */
    public class test01 {
    
        @Test
        public void testCollection1(){
            Collection coll = new ArrayList();
    
            //1.add(Object e):将元素e添加到集合coll中
            coll.add("AA");
            coll.add("BB");
            coll.add(new String("LaLa"));
            coll.add(123);
            coll.add(new Date());
    
            //2.size():获取添加的元素的个数
            System.out.println(coll.size());//5
    
            //3.addAll(Collection coll1):将coll1集合中的元素添加到当前的集合中
            Collection coll1 = new ArrayList();
            coll1.add(456);
            coll1.add("CC");
            coll1.addAll(coll);
    
            System.out.println(coll1.size());//7
    
            //4.clear():清空集合元素
            coll.clear();
    
            //5.isEmpty():判断当前集合是否为空
            System.out.println(coll.isEmpty());//true
    
    
        }
    
        @Test
        public void testCollection2(){
            Collection coll = new ArrayList();
            coll.add(123);
            coll.add(456);
            coll.add(new String("LaLa"));
    
            //6.contains(Object obj):判断当前集合中是否包含obj
            //判断时会调用obj对象所在类的equals()
            System.out.println(coll.contains(new String("LaLa")));//true
    
            //containsAll(Collection coll1):判断形参coll1中的所有元素是否都存在于当前集合中
            Collection coll1 = Arrays.asList(123, 456);
            System.out.println(coll.containsAll(coll1));//true
        }
    
        @Test
        public void testCollection3(){
            Collection coll = new ArrayList();
            coll.add(123);
            coll.add(456);
            coll.add(new String("Tom"));
            coll.add(false);
    
            //7.remove(Object obj):从当前集合中移除obj元素
            coll.remove(123);
            System.out.println(coll);//[456, Tom, false]
    
            //8.removeAll(Collection coll1):从当前集合中移除coll1中所有的元素(差集)
            Collection coll1 = Arrays.asList(456, 1234);
            coll.removeAll(coll1);
            System.out.println(coll);//[Tom, false]
        }
    
        @Test
        public void testCollection4(){
            Collection coll = new ArrayList();
            coll.add(123);
            coll.add(456);
            coll.add(new String("Tom"));
            coll.add(false);
    
            //9.retainAll(Collection coll1):获取当前集合和coll1集合的交集,并返回给当前集合
            Collection coll1 = Arrays.asList(123, 456, 789);
            coll.retainAll(coll1);
            System.out.println(coll);//[123, 456]
    
        }
    
        @Test
        public void testCollection5(){
            Collection coll = new ArrayList();
            coll.add(123);
            coll.add(456);
            coll.add(new String("Tom"));
            coll.add(false);
            
            Collection coll1 = new ArrayList();
            coll1.add(123);
            coll1.add(456);
            coll1.add(new String("Tom"));
            coll1.add(false);
    
            //10.equals(Object obj):不仅要相等,还要有序
            System.out.println(coll.equals(coll1));//true
        }
    
        @Test
        public void testCollection6(){
            Collection coll = new ArrayList();
            coll.add(123);
            coll.add(456);
            coll.add(new String("Tom"));
            coll.add(false);
    
            //11.hashCode():返回当前对象的哈希值
            System.out.println(coll.hashCode());
    
        }
    
        @Test
        public void testCollection7(){
            Collection coll = new ArrayList();
            coll.add(123);
            coll.add(456);
            coll.add(new String("Tom"));
            coll.add(false);
    
            //12.集合 ---> 数组:toArray()
            Object[] arr = coll.toArray();
            for(int i = 0; i < arr.length; i++){
                System.out.println(arr[i]);
            }
    
            //拓展:数组 ---> 集合:调用Arrays类的静态方法asList()
            List<String> list = Arrays.asList(new String[]{"AA", "BB", "CC"});
            System.out.println(list);
    
            //但是要注意
            List arr2 = Arrays.asList(new int[]{123, 456});
            System.out.println(arr2.size());//1
            List arr3 = Arrays.asList(new Integer[]{123, 456});
            System.out.println(arr3.size());//2
        }
    }
    
    

    二、Collection子接口之一: List接口

    说明:

    • List集合类中元素有序、且可重复。
    • JDK API中List接口的实现类常用的有:ArrayList、LinkedList和Vector。

    1、常用方法

    List除了从Collection集合继承的方法外,List 集合里添加了一些根据索引来 操作集合元素的方法。

    import org.junit.Test;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.List;
    
    /**
     * void add(int index, Object ele):在index位置插入ele元素
     * boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来
     * Object get(int index):获取指定index位置的元素
     * int indexOf(Object obj):返回obj在集合中首次出现的位置
     * int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
     * Object remove(int index):移除指定index位置的元素,并返回此元素
     * Object set(int index, Object ele):设置指定index位置的元素为ele
     * List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex位置的子集合
     */
    public class test05 {
        @Test
        public void testList(){
            List list = new ArrayList();
            list.add(123);
            list.add(456);
            list.add("AA");
            list.add(new String("BB"));
            list.add(789);
    
            //1.void add(int index, Object ele):在index位置插入ele元素
            list.add(1, "BB");
    
    
            //2.boolean addAll(int index, Collection eles):从index位置开始将eles中的所有元素添加进来
            List list1 = Arrays.asList(1, 2, 3);
            list.addAll(list1);
    
            //3.Object get(int index):获取指定index位置的元素
            System.out.println(list.get(1));
    
            //4.int indexOf(Object obj):返回obj在集合中首次出现的位置。如果不存在,返回-1。
            int index = list.indexOf(456);
            System.out.println(index);
    
            //5.int lastIndexOf(Object obj):返回obj在当前集合中末次出现的位置
            System.out.println(list.lastIndexOf(456));
    
            //6.Object remove(int index):移除指定index位置的元素,并返回此元素
            Object obj = list.remove(0);
    
            //7.Object set(int index, Object ele):设置指定index位置的元素为ele
            list.set(1, "CC");
    
            //8.List subList(int fromIndex, int toIndex):返回从fromIndex到toIndex位置左闭右开区间的子集合
            List subList = list.subList(2, 4);
        }
    }
    
    

    2、List实现类之一:ArrayList

    说明:

    • ArrayList 是 List 接口的典型实现类、主要实现类
    • ArrayList的JDK1.8之前与之后的实现区别?
      • JDK1.7:ArrayList像饿汉式,直接创建一个初始容量为10的数组
      • JDK1.8:ArrayList像懒汉式,一开始创建一个长度为0的数组,当添加第一个元 素时再创建一个始容量为10的数组
    • Arrays.asList(…) 方法返回的 List 集合,既不是 ArrayList 实例,也不是 Vector 实例。 Arrays.asList(…) 返回值是一个固定长度的 List 集合

    3、List实现类之二:LinkedList

    说明:

    • 对于频繁的插入或删除元素的操作,建议使用LinkedList类,效率较高 。
    • LinkedList:双向链表,内部没有声明数组,而是定义了Node类型的first和last, 用于记录首末元素。同时,定义内部类Node,作为LinkedList中保存数据的基 本结构。Node除了保存数据,还定义了两个变量:prev(变量记录前一个元素的位置 )和 next(变量记录下一个元素的位置)。
    • 新增方法:
      • void addFirst(Object obj)
      • void addLast(Object obj)
      • Object getFirst()
      • Object getLast()
      • Object removeFirst()
      • Object removeLast()

    4、List 实现类之三:Vector

    说明:

    • Vector 是一个古老的集合,JDK1.0就有了。大多数操作与ArrayList 相同,区别之处在于Vector是线程安全的。
    • 在各种list中,最好把ArrayList作为缺省选择。当插入、删除频繁时, 使用LinkedList;Vector总是比ArrayList慢,所以尽量避免使用。
    • 新增方法:
      • void addElement(Object obj)
      • void insertElementAt(Object obj,int index)
      • void setElementAt(Object obj,int index)
      • void removeElement(Object obj)
      • void removeAllElements()

    三、 Collection子接口之二: Set接口

    说明:

    • Set接口是Collection的子接口,set接口没有提供额外的方法。
    • Set 集合不允许包含相同的元素,如果试把两个相同的元素加入同一个 Set 集合中,则添加操作失败。
    • Set 判断两个对象是否相同不是使用 == 运算符,而是根据 equals() 方法

    1、Set实现类之一:HashSet

    说明:

    • HashSet 是 Set 接口的典型实现,大多数时候使用 Set 集合时都使用这个实现类。

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

    • HashSet 集合判断两个元素相等的标准:两个对象通过 hashCode() 方法比较相等,并且两个对象的 equals() 方法返回值也相等。

    • 对于存放在Set容器中的对象,对应的类一定要重写equals()和hashCode(Object obj)方法,以实现对象相等规则。即:“相等的对象必须具有相等的散列码”。

    • 向HashSet中添加元素的过程:

      当向 HashSet 集合中存入一个元素时,HashSet 会调用该对象的 hashCode() 方法 来得到该对象的 hashCode 值,然后根据 hashCode 值,通过某种散列函数决定该对象 在 HashSet 底层数组中的存储位置。(这个散列函数会与底层数组的长度相计算得到在 数组中的下标,并且这种散列函数计算还尽可能保证能均匀存储元素,越是散列分布, 该散列函数设计的越好)。

      如果两个元素的hashCode()值相等,会再继续调用equals方法,如果equals方法结果 为true,添加失败;如果为false,那么会保存该元素,但是该数组的位置已经有元素了, 那么会通过链表的方式继续链接。

    • 底层也是数组,初始容量为16,当如果使用率超过0.75,(16*0.75=12) 就会扩大容量为原来的2倍。(16扩容为32,依次为64,128....等)

    2、Set实现类之二:LinkedHashSet

    说明:

    • LinkedHashSet 是 HashSet 的子类。
    • LinkedHashSet 根据元素的 hashCode 值来决定元素的存储位置, 但它同时使用双向链表维护元素的次序,这使得元素看起来是以插入 顺序保存的。
    • LinkedHashSet插入性能略低于 HashSet,但在迭代访问 Set 里的全 部元素时有很好的性能。

    3、Set实现类之三:TreeSet

    说明:

    • TreeSet 是 SortedSet 接口的实现类,TreeSet 可以确保集合元素处于排序状态。

    • TreeSet底层使用红黑树结构存储数据 。

    • 新增方法:

      • Comparator comparator()
      • Object first()
      • Object last()
      • Object lower(Object e)
      • Object higher(Object e)
      • SortedSet subSet(fromElement, toElement)
      • SortedSet headSet(toElement)
      • SortedSet tailSet(fromElement)
    • 只能向TreeSet中添加类型相同的对象。否则发生ClassCastException异常。

      @Test
      public void test1(){
          TreeSet set = new TreeSet();
      
          //失败:不能添加不同类的对象
          //        set.add(123);
          //        set.add(456);
          //        set.add("AA");
          //        set.add(new User("Tom",12));
      
          //举例一:
          //        set.add(34);
          //        set.add(-34);
          //        set.add(43);
          //        set.add(11);
          //        set.add(8);
      
          //举例二:
          set.add(new User("Tom",12));
          set.add(new User("Jerry",32));
          set.add(new User("Jim",2));
          set.add(new User("Mike",65));
          set.add(new User("Jack",33));
          set.add(new User("Jack",56));
      
      
          Iterator iterator = set.iterator();
          while(iterator.hasNext()){
              System.out.println(iterator.next());
          }
      
      }
      
    • TreeSet 两种排序方法:自然排序和定制排序。默认情况下,TreeSet 采用自然排序。

      //自然排序
      //按照姓名从大到小排列,年龄从小到大排列
          @Override
          public int compareTo(Object o) {
              if(o instanceof User){
                  User user = (User)o;
      //            return -this.name.compareTo(user.name);
                  int compare = -this.name.compareTo(user.name);
                  if(compare != 0){
                      return compare;
                  }else{
                      return Integer.compare(this.age,user.age);
                  }
              }else{
                  throw new RuntimeException("输入的类型不匹配");
              }
      
          }
      
      @Test
      public void test2(){
          Comparator com = new Comparator() {
              //按照年龄从小到大排列
              @Override
              public int compare(Object o1, Object o2) {
                  if(o1 instanceof User && o2 instanceof User){
                      User u1 = (User)o1;
                      User u2 = (User)o2;
                      return Integer.compare(u1.getAge(),u2.getAge());
                  }else{
                      throw new RuntimeException("输入的数据类型不匹配");
                  }
              }
          };
      
          TreeSet set = new TreeSet(com);
          set.add(new User("Tom",12));
          set.add(new User("Jerry",32));
          set.add(new User("Jim",2));
          set.add(new User("Mike",65));
          set.add(new User("Mary",33));
          set.add(new User("Jack",33));
          set.add(new User("Jack",56));
      
      
          Iterator iterator = set.iterator();
          while(iterator.hasNext()){
              System.out.println(iterator.next());
          }
      }
      

    四、Map接口

    说明:

    • Map与Collection并列存在。用于保存具有映射关系的数据:key-value 。
    • Map 中的 key 和 value 都可以是任何引用类型的数据。
    • Map 中的 key 用Set来存放,不允许重复,即同一个 Map 对象所对应的类,须重写hashCode()和equals()方法。
    • Map接口的常用实现类:HashMap、TreeMap、LinkedHashMap和 Properties。其中,HashMap是 Map 接口使用频率最高的实现类。

    1、常用方法:

    @Test
    public void test3(){
        Map map = new HashMap();
        //1.Object put(Object key,Object value):将指定key-value添加到(或修改)当前map对象中
        map.put("AA",123);
        map.put(45,123);
        map.put("BB",56);
        map.put("AA",87);
    
        Map map1 = new HashMap();
        map1.put("CC",123);
        map1.put("DD",123);
    
        //2.void putAll(Map m):将m中的所有key-value对存放到当前map中
        map.putAll(map1);
    
        //3.Object remove(Object key):移除指定key的key-value对,并返回value
        Object value = map.remove("CC");
        System.out.println(value);
        System.out.println(map);
    
        //4.void clear():清空当前map中的所有数据
        map.clear();//与map = null操作不同
        System.out.println(map.size());
        System.out.println(map);
    }
    
    @Test
    public void test4(){
        Map map = new HashMap();
        map.put("AA",123);
        map.put(45,123);
        map.put("BB",56);
    
        //5.Object get(Object key):获取指定key对应的valuey)
        System.out.println(map.get(45));
    
        //6.boolean containsKey(Object key):是否包含指定的key
        boolean isExist = map.containsKey("BB");
        System.out.println(isExist);
    
        //7.boolean containsValue(Object value):是否包含指定的value
        isExist = map.containsValue(123);
        System.out.println(isExist);
    
        map.clear();
        //8.int size():返回map中key-value对的个数
        System.out.println(map.size());
    
        //9.boolean isEmpty():判断当前map是否为空
        System.out.println(map.isEmpty());
    
        //10.boolean equals(Object obj):判断当前map和参数对象obj是否相等
    
    }
    
    @Test
    public void test5(){
        Map map = new HashMap();
        map.put("AA",123);
        map.put(45,1234);
        map.put("BB",56);
    
        //11.Set keySet():返回所有key构成的Set集合
        Set set = map.keySet();
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    
        //12.Collection values():返回所有value构成的Collection集合
        Collection values = map.values();
        for(Object obj : values){
            System.out.println(obj);
        }
    
        //13.Set entrySet():返回所有key-value对构成的Set集合
        Set entrySet = map.entrySet();
        Iterator iterator1 = entrySet.iterator();
        while (iterator1.hasNext()){
            Object obj = iterator1.next();
            //entrySet集合中的元素都是entry
            Map.Entry entry = (Map.Entry) obj;
            System.out.println(entry.getKey() + "---->" + entry.getValue());
    
        }
        System.out.println();
        //方式二:
        Set keySet = map.keySet();
        Iterator iterator2 = keySet.iterator();
        while(iterator2.hasNext()){
            Object key = iterator2.next();
            Object value = map.get(key);
            System.out.println(key + "=====" + value);
    
        }
    
    }
    

    2、Map实现类之一:HashMap

    说明:

    • HashMap是 Map 接口使用频率最高的实现类。
    • 允许使用null键和null值,与HashSet一样,不保证映射的顺序。
    • 所有的key构成的集合是Set:无序的、不可重复的。所以,key所在的类要重写:equals()和hashCode()。
    • 一个key-value构成一个entry。
    • JDK 7及以前版本:HashMap是数组+链表结构(即为链地址法) 。JDK 8版本发布以后:HashMap是数组+链表+红黑树实现。

    3、Map实现类之二:LinkedHashMap

    说明:

    • LinkedHashMap 是 HashMap 的子类。
    • 在HashMap存储结构的基础上,使用了一对双向链表来记录添加元素的顺序。
    • 与LinkedHashSet类似,LinkedHashMap 可以维护 Map 的迭代顺序:迭代顺序与 Key-Value 对的插入顺序一致。

    4、Map实现类之三:TreeMap

    说明:

    • TreeMap存储 Key-Value 对时,需要根据 key-value 对进行排序。 TreeMap 可以保证所有的 Key-Value 对处于有序状态。
    • TreeSet底层使用红黑树结构存储数。
    • 自然排序、定制排序

    5、Map实现类之四:Hashtable

    说明:

    • Hashtable是个古老的 Map 实现类,JDK1.0就提供了。不同于HashMap, Hashtable是线程安全的。
    • Hashtable实现原理和HashMap相同,功能相同。底层都使用哈希表结构,查询 速度快,很多情况下可以互用。
    • 与HashMap不同,Hashtable 不允许使用 null 作为 key 和 value。

    6、Map实现类之五:Properties

    • Properties 类是 Hashtable 的子类,该对象用于处理属性文件。
    • 由于属性文件里的 key、value 都是字符串类型,所以 Properties 里的 key 和 value 都是字符串类型。
    • 存取数据时,建议使用setProperty(String key,String value)方法和 getProperty(String key)方法。
    public class PropertiesTest {
    
        //Properties:常用来处理配置文件。key和value都是String类型
        public static void main(String[] args)  {
            FileInputStream fis = null;
            try {
                Properties pros = new Properties();
    
                fis = new FileInputStream("jdbc.properties");
                pros.load(fis);//加载流对应的文件
    
                String name = pros.getProperty("name");
                String password = pros.getProperty("password");
    
                System.out.println("name = " + name + ", password = " + password);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if(fis != null){
                    try {
                        fis.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
    
                }
            }
    
        }
    }
    
  • 相关阅读:
    CentOS VPS
    Make 命令教程
    Nginx 学习
    字体对齐问题
    postman curl
    linux命令
    服务器
    操作系统
    nginx-1.15遇到无法加载php文件报404的问题
    thinkphp6.0框架下载与安装
  • 原文地址:https://www.cnblogs.com/xiaoran991/p/12593761.html
Copyright © 2020-2023  润新知