栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Java集合相关知识

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Java集合相关知识

JAVA集合 Java集合框架概述: 集合与数组
  1. 集合与数组储存数据概述

    集合、数组都是对多个数据进行存储操作的结构,简称Java容器

    说明:此时的存储,主要指的是内存层面的存储,不涉及到持久化的存储(.txt .jpg .avi 数据库中)

  2. 数组存储的特点

    • 一旦初始化以后,其长度就确定了
    • 数组一旦定义好,其元素的类型也就确定了,我们也就只能操作指定类型的数据了
  3. 数组存储的弊端

    • 一旦初始化后,其长度就不可修改
    • 数组中提供的方法非常有限,对于添加、删除、插入数据等操作,非常不便,同时效率不高
    • 获取数组中实际元素的个数的需求,数组没有现成的属性或方法可用
    • 数组存储数据的特点:有序、可重复。对于无序不可重复的需求,不能满足
  4. 集合存储的优点

    解决数组存储数据方面的弊端

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

    • List:元素有序、可重复的集合 “动态”数组

      ------ArrayList,linkedList,Vector

    • Set:元素无序、不可重复的集合 高中讲的“集合”

      ------HashSet、linkedHashSet、TreeSet

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

    ------HashMap、linkedHashMap、TreeMap、Hashtable、Properties


Collection接口继承树

Collection接口常用方法 add,size() ,addAll,isEmpty,clear
public void test1(){
    Collection coll = new ArrayList();
    //add(Object e)方法  将元素e添加到集合coll中
    coll.add("AA");
    coll.add("BB");
    coll.add(123);
    coll.add(new Date());

    //size()   获取添加的元素个数
    System.out.println(coll.size());//4

    //addAll(Collection coll1):将coll1集合中的元素添加到当前集合中
    Collection coll1 = new ArrayList();
    coll1.add(456);
    coll1.add("CC");
    coll.addAll(coll1);
    System.out.println(coll.size());//6
    System.out.println(coll);//[AA, BB, 123, Tue Oct 26 19:04:57 GMT+08:00 2021, 456, CC]



    //isEmpty() 判断当前集合是否为空(是否有元素)
    System.out.println(coll.isEmpty());//false
    
    //clear()  清空元素
    coll.clear();//清空元素
    System.out.println(coll.isEmpty());//true
}
contains,containsAll
  • Person类:

    public class Person {
        private String name;
        private int age;
    
        public Person() {
        }
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + ''' +
                    ", age=" + age +
                    '}';
        }
    
        @Override
        public boolean equals(Object o) {
            System.out.println("Person equals()……");
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;
    
            Person person = (Person) o;
    
            if (age != person.age) return false;
            return name != null ? name.equals(person.name) : person.name == null;
        }
    
        
    }
    
  • 测试

    public void test2(){
        Collection coll = new ArrayList();
        //Person person = new Person("小明", 21);
        coll.add(new String("XP"));
        coll.add(false);
        coll.add(123);
        coll.add(456);
        coll.add(new Person("小明", 21));
    
        //contains(Object obj)判断当前集合中是否包含obj  (调用obj 所在类的equals()方法判断内容)
        System.out.println(coll.contains(123));//true
        System.out.println(coll.contains(12));//false
        System.out.println(coll.contains("XP"));//true
        System.out.println(coll.contains(new String("XP")));//true
        System.out.println(coll.contains(new Person("小明", 21)));//false
        System.out.println(coll);
                     // 重写equals后变成true:
                    
        //containsAll(Collection coll1)判断形参coll1是否都存在于当前集合中
        Collection coll1 = Arrays.asList(123,456);
        System.out.println(coll.containsAll(coll1));//true
    }
    
remove,removeAll,retainAll,equals
public void test3(){
    Collection coll = new ArrayList();
    coll.add("XP");
    coll.add(false);
    coll.add(123);
    coll.add(456);
    coll.add(new Person("小明", 21));
    //remove(Object obj)移除,若没有指定的元素,则返回false (会调用equals()方法)
    System.out.println(coll);//[XP, false, 123, 456, Person{name='小明', age=21}]
    System.out.println(coll.remove(123));//true
    System.out.println(coll.remove(1234));//false
    System.out.println(coll);//[XP, false, 456, Person{name='小明', age=21}]

    //removeAll(Collection coll1)  从当前集合中移除coll1中的所共有的元素(获取差集并返回给当前集合)
    Collection coll1 = new ArrayList();
    coll1.add(1234);
    coll1.add(456);
    System.out.println(coll.removeAll(coll1));//true
    System.out.println(coll);//[XP, false, Person{name='小明', age=21}]

    //retainAll  获取当前集合中找出与coll1中的所共有的元素(获取交集并返回给当前集合)
    coll1.add("XP");
    coll1.add(false);
    System.out.println(coll.retainAll(coll1));//true
    System.out.println(coll);//[XP, false]

    //equals(Object obj): 判断两个集合的元素是否相同
    Collection coll2 = new ArrayList();
    coll2.add("XP");
    coll2.add(false);


    System.out.println(coll);//[XP, false]
    System.out.println(coll2);//[XP, false]
    System.out.println(coll.equals(coll2));//true  因为利用的是ArrayList();是有序的,所以交换元素顺序会影响判断结果

}
hasCode,toArray
public void test4(){
    Collection coll = new ArrayList();
    coll.add("XP");
    coll.add(false);
    coll.add(123);
    coll.add(456);
    coll.add(new Person("小明", 21));

    //hasCode() 返回当前对象的哈希值
    System.out.println(coll.hashCode());//-1172761429

    //toArray()  将集合转化为数组
    Object[] arr = coll.toArray();
    System.out.println(Arrays.toString(arr));//[XP, false, 123, 456, Person{name='小明', age=21}]

    //拓展:调用Arrays的静态方法:asList()  数组--->集合
    List list = Arrays.asList(new String[]{"AA", "bb"});
    System.out.println(list);//[AA, bb]

    List arr1 = Arrays.asList(new int[]{123,456,789});//写成这样会默认认为是一个元素
    System.out.println(arr1);//[[I@ba8a1dc]
    System.out.println(arr1.size());//1

    List arr2 = Arrays.asList(new Integer[]{123,456,789});
    System.out.println(arr2);//[123, 456, 789]
    System.out.println(arr2.size());//3

    //iterator(): 返回iterator接口的实例,用于遍历集合元素,放在IteratorTest.java中测试
    

}
迭代器Iterator接口遍历集合元素

  • 遍历
public void test1(){
        Collection coll = new ArrayList();
        coll.add("XP");
        coll.add(false);
        coll.add(123);
        coll.add(456);
        coll.add(new Person("小明", 21));

        Iterator iterator = coll.iterator();
       
        
        //方式三:推荐  调用hasNext()判断是否还有元素
       // hasNext()判断是否还有下一元素
        while (iterator.hasNext()){
            //next()指针下移,将下移后集合位置上的元素返回
            System.out.println(iterator.next());
        }


    }
  • 移除迭代器指向元素的操作

    public void test2(){
        Collection coll = new ArrayList();
        coll.add("XP");
        coll.add(false);
        coll.add(123);
        coll.add(456);
        coll.add(new Person("小明", 21));
    
        Iterator iterator = coll.iterator();
        while (iterator.hasNext()){
            Object o = iterator.next();
            if(o.equals("XP")){
                iterator.remove();
            }
        }
        Iterator iterator1 = coll.iterator();
        while (iterator1.hasNext()){
            System.out.print(iterator1.next()+"t");
       //false 123    456    Person{name='小明', age=21}  
    
        }
    }
    
  • 使用(JDK5新特性)foreach循环遍历集合(内部仍然调用迭代器)

    public void test3(){
        Collection coll = new ArrayList();
        coll.add("XP");
        coll.add(false);
        coll.add(123);
        coll.add(456);
        coll.add(new Person("小明", 21));
    
        //for(集合中元素的类型:集合对象)相当于把coll的元素赋值给obj,改变obj中的元素不会改变原有集合中的元素
        for(Object obj:coll){
            System.out.print(obj+"t");
            //XP   false  123    456    Person{name='小明', age=21}  
        }
    }
    
List接口
  • ArrayList、linkedList、Vector不同点

    • ArrayList:作为List接口的主要实现类,执行效率高(线程不安全),底层使用Object[] elementData存储

    • linkedList:底层使用双向链表存储,对于频繁的插入、删除操作,使用此类效率比ArrayList高

    • Vector:作为List接口的古老实现类,执行效率低(线程安全),底层使用Object[] elementData存储

  • 相同点:三个类都实现了List接口,存储数据的特点相同,存储有序的可重复的数据

List接口常用方法测试
  • 总结:

    • 增:add(Object ele)

    • 删:remove(int index)

    • 改:sublist(int fromIndex,int toIndex)

    • 查:get(int index)

    • 插:add(int index,Object ele)

    • 长度:size()

    • 遍历:

      1. Iterator

      2. 增强for循环

  • add,addAll,get

public void test1(){
    ArrayList list = new ArrayList();
    list.add(123);
    list.add(456);
    list.add("AA");
    list.add(new Person("小华",22));
    list.add(456);//支持重复元素

    System.out.println(list);//[123, 456, AA, Person{name='小华', age=22}, 456]
    //void add(int index,Object ele) 在index位置插入ele元素
    list.add(1,"BB");
    System.out.println(list);//[123, BB, 456, AA, Person{name='小华', age=22}, 456]

    //boolean addAll(int index,Collection eles):从index开始将eles中的所有元素插入
    List list1 = Arrays.asList(1, 2, 3);
    System.out.println(list.size());//6
    System.out.println(list.addAll(list1));//true 默认加到最后
    // 若不慎写成add,则会将list1看成一个元素加进去
    System.out.println(list.size());//9
    System.out.println(list);//[123, BB, 456, AA, Person{name='小华', age=22}, 456, 1, 2, 3]

    //Object get(int index): 获取指定index位置的元素
    System.out.println(list.get(2));//456
    


}
  • indexOf,lastIndexOf,remove,set,sublist
public void test2(){
    ArrayList list = new ArrayList();
    list.add(123);
    list.add(456);
    list.add("AA");
    list.add(new Person("小华",22));
    list.add(456);//支持重复元素

    //int indexOf(Object obj) 返回obj在集合中首次出现的位置
    int index = list.indexOf(456);
    System.out.println(index);//返回所在位置1
    System.out.println(list.indexOf(23311321));//不存在返回-1

    //int lastIndexOf(Object obj) 返回obj在集合中最后出现的位置
    System.out.println(list.lastIndexOf(456));//4

    //Object remove(int index):移除指定index位置的元素,并返回此元素
    Object o = list.remove(0);
    System.out.println(o);//123
    System.out.println(list);//[456, AA, Person{name='小华', age=22}, 456]

    //Object set(int index,Object ele):修改指定index位置的元素为ele,并返回该元素
    Object o1 = list.set(1, "cc");
    System.out.println(o1);//AA
    System.out.println(list);//[456, cc, Person{name='小华', age=22}, 456]

    //List sublist(int fromIndex,int toIndex):返回从fromIndex到toIndex位置的子集合,左闭右开,不会对原来的list造成影响
    List subList = list.subList(0, 2);
    System.out.println(list);//[456, cc, Person{name='小华', age=22}, 456]
    System.out.println(subList);//[456, cc]
    


}
  • 遍历的方法

    public void test3(){
        ArrayList list = new ArrayList();
        list.add(123);
        list.add(456);
        list.add("AA");
    
        //方式1
        Iterator iterator = list.iterator();
        while (iterator.hasNext()){
            System.out.print(iterator.next()+"t");//123 456 AA
        }
        System.out.println();
        //方式2
        for (Object o:list){
            System.out.print(o + "t");//123 456 AA
        }
        System.out.println();
        //方式3
        for (int i = 0; i < list.size(); i++) {
            System.out.print(list.get(i)+"t");//123 456 AA
            
        }
    }
    
Set接口
  • 实现类的对比

    • HashSet:作为Set接口的主要实现类:线程不安全的;可以存储null值

    • linkedHashSet:作为HashSet类的子类:遍历其内部数据时。可以按照添加的顺序遍历

    • TreeSet:可以按照添加对象的指定属性进行排序

  • 要求:

    1. 向Set中添加的数据,其所在的类一定要重写hasCode与equals方法
    2. 重写的hasCode与equals尽可能保持一致性
无序性
  • 不等于随机性
  • 存储的数据在底层数组中并非按照数组索引的顺序添加,而是根据数据的哈希值决定的
不可重复性
  • 保证添加的元素按照equals()方法判断时不能返回true,即相同元素只能添加一个

  • 示例:

    public void test1() {
        HashSet set = new HashSet();
        set.add(456);
        set.add(123);
        set.add("aa");
        set.add("cc");
        set.add(new Person("小花",18));
        set.add(new Person("小花",18));
        set.add(123);
    
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            System.out.print(iterator.next()+"t");//
        }
        //没有重写hasCode与equals时的结果,两个Person对象都出现,而两个123却只出现一次
        //aa   cc Person{name='小花', age=18}  456    Person{name='小花', age=18}  123
    
        //重写hasCode与equals时的结果,两个Person对象只有一个
        //Person equals()……
        //aa   cc 456    Person{name='小花', age=18}  123    
    }
    
添加元素的过程:以HashSet为例
  1. 我们向HashSet中添加元素a,首先调用元素a所在类型的hashCode()方法,计算元素a的哈希值

  2. 此哈希值通过某种算法计算出在HashSet底层数组中的存放位置(即为:索引位置),判断数组此位置上是否已经有元素

  3. 如果此位置上没有其他元素,则元素a添加成功—情况一

  4. 如果此位置上有其他元素b(或以链表形式存在的多个元素),则比较元素a与元素b的hash值,

    • 如果不相同,则元素a添加成功------情况二

    • 如果相同,调用元素a所在类的equals()方法,如果返回true,元素a添加失败,若返回false,则元素a添加成功--------情况三

ps:对于情况二和情况三而言,元素a与已经存在指定索引位置上的数据以链表的方式存储

  • jdk7:元素a放到数组中,指向原来的元 素
  • jdk8:原来的元素放在数组中,指向元素a(七上八下)
linkeHashSet类
  • 额外提供了双向链表,可以按照添加的顺序输出。
public void test2() {
    linkedHashSet set = new linkedHashSet();
    set.add(456);
    set.add(123);
    set.add("aa");
    set.add("cc");
    set.add(new Person("小花",18));
    set.add(new Person("小花",18));
    set.add(123);
    System.out.println(set);
    //额外提供了双向链表,可以按照添加的顺序输出,但是还是无序性,因为无序性指的是添加时的地址的无序性
    //[456, 123, aa, cc, Person{name='小花', age=18}]
}
  • 优点:对于频繁的遍历操作,效率较高
TreeSet类
  1. 向TreeSet中添加的数据,要求是相同类的对象
  2. 两种排序方式:自然排序(实现Comparable接口)和定制排序(实现Compartor)
  3. 自然排序中,比较两个对象相同的标准为:compareTo()返回0,不再用equals()方法去判断
  4. 定制排序中,比较两个对象相同的标准为:compare()返回0,不再用equals()方法去判断
  • 自然排序例子:

    public void test1(){
        TreeSet set = new TreeSet();
    
        set.add(34);
        set.add(-34);
        set.add(44);
        set.add(11);
        set.add(8);
    
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            System.out.print(iterator.next()+"   ");
    
        }//-34   8   11   34   44 从小到大排序输出了
    }
    public void test2(){
        TreeSet set = new TreeSet();
        set.add(new Person("Ming",20));
        set.add(new Person("XiaoHu",24));
        set.add(new Person("Wei",18));
        set.add(new Person("Gala",21));
        set.add(new Person("Ming",25));
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
        //只按照姓名从小到大排列时:
        //Person{name='Gala', age=21}
        //Person{name='Wei', age=18}
        //Person{name='XiaoHu', age=24}
        //Person{name='XiaoMing', age=20}
        //没有出现另一个Ming,TreeSet的判断是否相同是按照CompareTo的返回值判断的
        //修改之后考虑年龄的结果:
        //Person{name='Gala', age=21}
        //Person{name='Ming', age=20}
        //Person{name='Ming', age=25}
        //Person{name='Wei', age=18}
        //Person{name='XiaoHu', age=24}
    
  • 定制排序

    public void test3(){
        Comparator comparator = new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {
                if(o1 instanceof Person && o2 instanceof Person){
                    Person p1 = (Person) o1;
                    Person p2 = (Person) o2;
                    return Integer.compare(p1.getAge(),p2.getAge());
                }else {
                    throw new RuntimeException("输入的类型不匹配");
                }
            }
        };
        
        TreeSet set = new TreeSet(comparator);
        set.add(new Person("Ming",20));
        set.add(new Person("XiaoHu",24));
        set.add(new Person("Wei",18));
        set.add(new Person("Gala",21));
        set.add(new Person("Ming",25));
        Iterator iterator = set.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    
练习:

注:Person类如下:

public class Person implements Comparable{
    private String name;
    private int age;

    public Person() {
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + ''' +
                ", age=" + age +
                '}';
    }

    @Override
    public boolean equals(Object o) {
        System.out.println("Person equals()……");
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Person person = (Person) o;

        if (age != person.age) return false;
        return name != null ? name.equals(person.name) : person.name == null;
    }

    @Override
    public int hashCode() {
        int result = name != null ? name.hashCode() : 0;
        result = 31 * result + age;
        return result;
    }

    //按照姓名从小到大排列,年龄从小到大排列
    @Override
    public int compareTo(Object o) {
        if(o instanceof Person) {
            Person person = (Person)o ;
            int compare = this.name.compareTo(person.name);
            if(0 != compare){
                return compare;
            }else {
                return Integer.compare(this.age,person.age);
            }
        }else {
            throw new RuntimeException("输入类型不匹配");
        }
    }
}
  1. 在List内取出重复数字值,要求尽量简单

    思路:利用set的不可重复性

    public void exercise1(){
        List list = new ArrayList();
        list.add(1);
        list.add(2);
        list.add(2);
        list.add(4);
        list.add(4);
        System.out.println(list);//[1, 2, 2, 4, 4]
        HashSet set = new HashSet();
        set.addAll(list);
        List list1 = new ArrayList(set);
        System.out.println(list1);//[1, 2, 4]
    }
    
  2. Person类中重写了hashCode()和equals()方法,问下面程序输出为什么?

    public void exercise2(){
        HashSet set = new HashSet();
        Person p1 = new Person("AA",1001);
        Person p2 = new Person("BB",1002);
    
        set.add(p1);
        set.add(p2);
        p1.setName("CC");
        set.remove(p1);
        System.out.println(set);//
        set.add(new Person("CC",1001));
        System.out.println(set);//
        set.add(new Person("AA",1001));
        System.out.println(set);//
    }
    

    **

    **

    **

    **

    **

    结果为:

    [Person{name=‘CC’, age=1001}, Person{name=‘BB’, age=1002}]

    [Person{name=‘CC’, age=1001}, Person{name=‘CC’, age=1001}, Person{name=‘BB’, age=1002}]

    [Person{name=‘CC’, age=1001}, Person{name=‘CC’, age=1001}, Person{name=‘AA’, age=1001}, Person{name=‘BB’, age=1002}]

    解析:

    1. 第一次添加时,是利用name=‘AA’, age=1001与name=‘BB’, age=1002计算的哈希值例如111,222,并放在了创造的数组里 假设为3号位置和11号位置

    2. p1.setName(“CC”);后,p1,p2的位置并未发生改变,只是p1中的name属性改变了

      set.remove(p1),寻找哈希值是利用此时的CC计算的哈希值,假设为333,所计算的位置为空,所以没有将原来的p1移除,第一次输出为上述第一次的答案

    3. set.add(new Person(“CC”,1001));时,设此元素为p3,利用CC计算哈希值,假设为333,利用333计算得到到一个索引值,假设为13号位置,将其放入

    4. set.add(new Person(“AA”,1001));时,设此元素为p4,利用AA计算哈希值,为111,利用111计算得到到一个索引值,3号位置,由于已存在元素,则调用equals方法判断是否相同,由于此时p1中的name属性以变为CC,所以判断p1,p4不相等,以链表方式存储,最终结果输出就有四个元素

Map接口 概念与理解
  • Map接口:双列数据,保存有映射关系“key-value对”的集合(映射 )

    ------HashMap:作为Map的主要实现类,线程不安全,效率高,存储null的key和value

    ​ ------linkedHashMap:保证在遍历map元素时,可以按照添加的顺序实现遍历

    ​ 原因:在原有的HashMap底层结构基础上,添加了一对指针,指向前一个和后一个元素,对于频繁的遍历操作,此类执行效率高于HashMap

    ------TreeMap:保证按照添加的key-value对进行排序,实现排序遍历,按照key来排序

    ​ 底层使用的红黑树

    ------Hashtable:作为古老的实现类,线程安全,效率低,不能存储null的key和value

    ​ ------Properties:常用来处理配置文件。key-value都是String类型

    public void test1(){
        HashMap map = new HashMap();
        map.put(null,123);//不会报错
        Hashtable hashtable = new Hashtable();
        hashtable.put(null,123);//会抛出NullPointerException异常
    }
    
  • HashMap的底层原理

    数组+链表(jdk7及之前)

    数组+链表+红黑树(jdk8)

  • 对Map结构的理解

    Map中的key:无序的、不可重复的,使用Set存储所有的key-----要求key所在的类要重写equals和hashCode()(以HashCode)为例

    value:无序的,可重复的,使用Collection存储所有的value----要求value所在的类要重写equals方法

    一个键值对:key-value构成了一个Entry对象

    entry:无序的、不可重复的,使用Set存储所有的entry

  • HashMap的底层实现原理,以jdk7 为例HashMap map = new HashMap();

    在实例化以后,底层创建了长度是16的一维数组Entry[] table

    可能已经执行过多次put

    map.put(key1,value1):

    首先,调用key1所在类的hashCode()计算key1哈希值,此哈希值经过某种算法计算以后,得到Entry数组中的存放位置。

    • 如果此位置上的数据为空,此时的key1-value1添加成功—情况一
    • 如果此位置上的数据不为空(意味这此位置上存在一个或多个数据(以链表形式存在)),比较key1和已经存在的一个或多个数据的哈希值:
      • 如果key1的哈希值与已经存在的数组的哈希值都不相同,此时可以添加成功—情况二
      • 如果key1的哈希值和已经存在的某一个哈希值相同,继续比较调用key1所在类的equals方法进行比较
        • 如果equals返回false,此时key1-value1添加成功—情况三
        • 如果equals返回true使用value1替换原来的value

    ps:对于情况二和情况三而言,元素a与已经存在指定索引位置上的数据以链表的方式存储

  • HashMap的底层实现原理,jdk8相较于jdk7的不同

    1. new HashMap();底层没有创建一个长度为16的数组

    2. jdk 8底层的数组是:Node[],而非Entry[]

    3. 首次调用put()方法时,底层创建长度为16的数组

    4. jdk7 底层结构只有数组+链表,jdk8中的底层结构为数组+链表+红黑树

      当数组的某一个索引位置上的元素以链表形式存在的数据个数>8,且当前数组的长度>64时,此时此索引位置上的所有数据改为使用红黑树存储

Map常用方法 增、删、改
public void test3(){
    //put()添加或修改
    HashMap map = new HashMap();
    map.put("AA",123);//添加
    map.put("BB",1234);//添加
    map.put("AA",114514);//修改
    System.out.println(map);//{AA=114514, BB=1234}

    //putAll():将map1中的元素添加或修改到map中去
    HashMap map1 = new HashMap();
    map1.put("CC",12322);
    map1.put("DD",114514);
    map1.put("BB",1313);

    map.putAll(map1);
    System.out.println(map);//{AA=114514, BB=1313, CC=12322, DD=114514}

    //remove(Object key):以key为关键字移除某一元素,返回key对应的value,不存在返回null
    Object ccValue = map.remove("CC");
    Object value = map.remove("CCvcasd");
    System.out.println(ccValue);//12322
    System.out.println(value);//null
    System.out.println(map);//{AA=114514, BB=1313, DD=114514}

    //clear():清除所有元素
    map.clear();
    System.out.println(map.size());//0
    System.out.println(map);//{}
}
查询
public void test4(){
    HashMap map = new HashMap();
    map.put("AA",123);//添加
    map.put("BB",1234);//添加

    //get(Object key)返回key对应的value,不存在返回null
    System.out.println(map.get("AA"));//123
    System.out.println(map.get("AAA"));//null

    //containKey(Object key):是否包含指定的key
    boolean containsAA = map.containsKey("AA");
    boolean containsAAA = map.containsKey("AAA");
    System.out.println(containsAA);//true
    System.out.println(containsAAA);//false

    //containValue(Object value):是否包含指定的value
    boolean aa = map.containsValue(123);
    boolean bb = map.containsValue(1233);
    System.out.println(aa);//true
    System.out.println(bb);//false

    //size():判断map中键值对个数
    System.out.println(map.size());//2

    //equals(Object obj):判断当前map和参数对象obj是否相等
    HashMap map1 = new HashMap();
    map1.put("AA",123);//添加
    map1.put("BB",1234);//添加
    System.out.println(map.equals(map1));//true
    //isEmpty(),判断是否为空
    map.clear();
    System.out.println(map.size());//0
    System.out.println(map.isEmpty());//true

    
}
元视图操作方法(遍历)
public void test5(){
    HashMap map = new HashMap();
    map.put("AA",123);//添加
    map.put("BB",1234);//添加
    map.put("CC",114514);//添加

    //遍历所有的key集
    //keySet()返回所有的key构成的Set集合
    Set set = map.keySet();
    for(Object key:set){
        System.out.print(key + "    ");
    }//AA   BB   CC

    System.out.println();

    //遍历所有的value集合
    //values()返回所有的value构成的Collection集合
    Collection value = map.values();
    Iterator iterator = value.iterator();
    while (iterator.hasNext()){
        System.out.print(iterator.next()+"   ");
    }//123   1234   114514

    System.out.println();

    //遍历所有的key-value集合
    //方式一: entrySet();返回所有entry构成的Set集合
    for (Object obj : map.entrySet()) {
        System.out.print(obj + "   ");
    }//AA=123   BB=1234   CC=114514
    System.out.println();
    for (Object obj : map.entrySet()) {
        Map.Entry entry = (Map.Entry) obj;
        System.out.print(entry.getKey() + "----->" + entry.getValue() + "   ");
    }//AA----->123BB----->1234CC----->114514
    System.out.println();
    //方式二:利用之前的方法自己写
    Set keySet = map.keySet();
    Iterator iterator1 = keySet.iterator();
    while(iterator1.hasNext()){
        Object keyNext = iterator1.next();
        Object valueNext = map.get(keyNext);
        System.out.print(keyNext + ">>>>" +valueNext+"   ");
    }//AA>>>>123   BB>>>>1234   CC>>>>114514

}
利用TreeMap排序
  • 自然排序

    public void test1(){//自然排序
        TreeMap treeMap = new TreeMap();
    
        Person p1 = new Person("Ming",21);
        Person p2 = new Person("Wei",18);
        Person p3 = new Person("XiaoHu",25);
        Person p4 = new Person("Gala",19);
        Person p5 = new Person("Cryin",21);
        treeMap.put(p1,"辅助");
        treeMap.put(p2,"打野");
        treeMap.put(p3,"上单");
        treeMap.put(p4,"AD");
        treeMap.put(p5,"中单");
    
        //自然排序
        for (Object obj : treeMap.entrySet()) {
            Map.Entry entry = (Map.Entry) obj;
            System.out.println(entry.getKey() + " >> " + entry.getValue());
        }
        
    
    }
    
  • 定制排序

    public void test2(){//定制排序(年龄由大到小)
        TreeMap treeMap = new TreeMap(new Comparator() {
            @Override
            public int compare(Object o, Object t1) {
                if(o instanceof Person && t1 instanceof Person){
                    Person pp1 = (Person) o;
                    Person pp2 = (Person) t1;
                    return Integer.compare(pp1.getAge(),pp2.getAge());
                }else {
                    throw new RuntimeException("输入数据类型不匹配");
                }
    
            }
        });
    
        Person p1 = new Person("Ming",22);
        Person p2 = new Person("Wei",18);
        Person p3 = new Person("XiaoHu",25);
        Person p4 = new Person("Gala",19);
        Person p5 = new Person("Cryin",21);
        treeMap.put(p1,"辅助");
        treeMap.put(p2,"打野");
        treeMap.put(p3,"上单");
        treeMap.put(p4,"AD");
        treeMap.put(p5,"中单");
    
        for (Object obj : treeMap.entrySet()) {
            Map.Entry entry = (Map.Entry) obj;
            System.out.println(entry.getKey() + " >> " + entry.getValue());
        }
    
    }
    
Properties类
  • 在工程文件下新建

  • 对中文操作需要勾上如下图所示的位置

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Properties;

public class PropertiesTest {
    public static void main(String[] args) {
        Properties pros = new Properties();

        FileInputStream file = null;
        try {
            file = new FileInputStream("集合/jdbc.properties");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        try {
            pros.load(file);//加载对应的文件
        } catch (IOException e) {
            e.printStackTrace();
        }

        String name = pros.getProperty("name");
        String password = pros.getProperty("password");

        System.out.println("name = "+name+", password = "+password);
        //name = 翔, password = abc123
        try {
            file.close();
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}
Collections工具类
  • 定义:操作Collection和Map的工具类

  • Collection和Collections的区别

    Collection是接口, Collections是工具类

常用方法
public void test1(){
    ArrayList list = new ArrayList();
    list.add(456);
    list.add(123);
    list.add(733);
    list.add(114514);
    System.out.println(list);//[456, 123, 733, 114514]

    //reverse(List) 反转List元素的顺序
    Collections.reverse(list);
    System.out.println(list);//[114514, 733, 456, 123]
    //shuffle(list)对List集合元素进行随机排序
    Collections.shuffle(list);
    System.out.println(list);
      //第一次运行:[114514, 123, 733, 456]
      //第二次运行:[114514, 123, 456, 733]
    //sort(List) 自然排序  sort(list,Comparator) 定制排序
        Collections.sort(list, new Comparator() {
            @Override
            public int compare(Object o, Object t1) {
                if(o instanceof Integer && t1 instanceof Integer){
                    Integer i1 = (Integer) o;
                    Integer i2 = (Integer) t1;
                    return -Integer.compare(i1,i2);
                }else {
                    throw new RuntimeException("输入数据类型错误");
                }
            }
        });
        System.out.println("定制排序结果为:"+list);//[114514, 733, 456, 123]
        Collections.sort(list);
        System.out.println("自然排序结果为:"+list);//[123, 456, 733, 114514]

    //swap(List list,int index1,int index2)交换索引位置处的两个元素
    Collections.swap(list,1,2);//[123, 456, 733, 114514]

    //Object max(Collection) 返回自然顺序中最大值
    System.out.println(Collections.max(list));//114514
    //Object min(Collection) 返回自然顺序中最小值
    System.out.println(Collections.min(list));//123

    //int frequency(Collection,Object)返回指定集合中指定元素的出现次数
    list.add(114514);
    System.out.println(Collections.frequency(list,114514));//2
    System.out.println(Collections.frequency(list,111));//0
    System.out.println(Collections.frequency(list,123));//1

    //void copy(List dest,List src) 将src中的内容复制到dest中
        
        //正确做法:
    List list1 =  Arrays.asList(new Object[list.size()]);
    System.out.println(list1.size());//5
    Collections.copy(list1,list);
    System.out.println(list1);//[123, 733, 456, 114514, 114514]
}
 
  • 解决线程安全问题的方法

    public void test2(){
        ArrayList list = new ArrayList();
        list.add(456);
        list.add(123);
        list.add(733);
        list.add(114514);
        System.out.println(list);//[456, 123, 733, 114514]
    
        //Collections.synchronizedXXX() 方法,返回的集合为线程安全的
        List list1 = Collections.synchronizedList(list);//返回的list1即为线程安全的
    }
    
转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号