• Java的集合框架


    Java集合框架综述

    1:集合框架(Collection Framework)

    首先要知道 集合代表的是一组对象,和数组差不多 但是数组的长度是固定不变的,而集合是可以变换长度的,比如说:集合就是一根金箍棒,可长可短, 数组就像是一根普通的木棍,长度是固定的,不能变长或者变短。在Java的集合框架中定义了一套规范用来操作集合和具体实现细节,在这里呢也可以把集合想象成一个数据库 ,它有“增删改查”四种操作 ,在本章呢会介绍集合框架的基本类和接口和一些的基本操作方法。

    2:集合框架的两大接口(Collection和Map)

    1.Collection接口

    Collection表示一组对象 ,这些对象也称为collection元素,一个collection允许有重复的值,而另一些则不允许,一些collection是有序的,而有一些是无序的,在Java中没有直接实现collection的 但是它提供了两个子接口 这两个子接口继承了collection接口,那是哪两个接口呢?

    ヾ(✿゚▽゚)ノ  这里介绍两个collection接口的子接口    List   和   Set  

    1.1ArraysLIst类

    ArrayList是List的一个实现类。每一个ArrayList实例都有一个容量,该容量是指用来存储列表的数组大小,它总是等于或者小于列表的大小,随着向ArrayList不断添加元素,其容量也不断的增大。这里ArrayList它跟数组有很多相同点,到底有什么相同点和不同点呢?如下

    那知道ArrayList的概念 怎么创建一个ArrayList集合呢?  定义语法如下:

     1 //创建ArrayList集合 2 List list = new ArraysList(0); 

     在创建ArrayList集合的时候需要导入包:

    //导入包
    import
    java.util.ArrayList; import java.util.List;

    知道了创建ArrayList集合 那怎么向集合里添加元素呢  开始说过java集合框架中定义了一套规范来实现“增伤改查”那怎么实现具体操作呢?下面介绍ArrayList集合的常用方法:

    ArraysLIst 集合的常用方法
    Arrays.asList(); 将数组装换为集合 
    add(Object value); 添加元素
    add(int index,Object value)向指定位置插入元素 
    get(int index);通过下标获取元素 
    set(intindex,Object value);修改指定位置的元素 
    remove(int index); 移除集合中指定位置的元素
    remove(Object o);从集合中移除第一次出现的指定元素(如果存在) 
    removeAll(collection<?>c);从列表中移除制动的collection 中包含的所有元素
    Clear (); 移除集合中所有的元素
    //遍历ArrayList
    foreach(Object item : list){
        //通过get()方法获取元素
    }

    需要注意的是: 1.存储的元素类型都是Object类型

            2.ArrayList集合中是可以添加重复的值,这个跟数组是一样的

                              3. 它的初始容量为10的空列表

    1.2HashSet类

     HashSet是一个哈希集是set的一个重要实现类 它不保证顺序恒久不变,也就是说是无序的,它允许使用NUll元素  但是只能有一个。而且他还不能有重复的值。set中 添加某个对象 无论添加多少次  最终只会保留一个该对象(的引用) 并且 保留的是第一次添加的那一个。既然是无序的所以它没有索引,不能通过索引获取元素。同样跟ArrayList一样它储存的类型也是Object类型。

    那怎么创建一个Hashset呢?  代码如下:

    //创建HashSet(哈希集)
    HashSet hashset= new HashSet();

    在创建HashSet实例时需要导入包:

    import java.util.HashSet;

     

    以下是HashSet类的一些常用方法   如下图:

    add(Object value) 如果此 set中尚未包含指定元素,则添加指定元素 它的返回值是Boolean类型
    
    clear() 移除所有元素
    
    remove(Object o)如果指定元素存在于此 set 中,则将其移除 它的返回值是Boolean类型
    
    size()获取set中的元素的数量  返回值是int
    
    isEmpty()判断该set中是否包含任何元素 返回值是boolean类型
    
    iterator() 返回对此 set 中元素进行迭代的迭代器。

    大家看到Hashset并没有直接获取元素的方法,因为他是无序的 没有索引,这里我们用iterator()方法迭代获取数据,那怎么用呢?代码如下:

     

    import java.util.Iterator;//导包

    itIterator i = hash.iterator(); while(i.hasNext()){ String str = (String)i.next();//需要强转 }

    这里需要注意的是  HashSet里储存是Object类型  需要什么数据类型 就强转成什么数据类型

    上面的是通过Iterator()方法进行迭代  看起来比较麻烦  所以还有一种渐变的方法  通过foreach迭代器进行获取数据 代码如下:

    foreach(Object item in hash){
    
          //获取数据        
    
    }

     上面是Collection接口中的两个子接口 List和Set 下面介绍另一个接口  Map

    2.Map接口

    Map提供了一种映射关系 其中的元素是以键值对(Key-value)的形式存储的 能够实现根据key快速查找Value

    Map中的键值对以Entry类型的对象实例形式存在

    健(key值)不可重复 value值可以
    一个值可以跟很多的key进行映射关系 但一个健(key值)最多只能映射到一个值(value)

     2.1 HashMap类

     HashMap是map的一个重要实现,也是最常用的 基于哈希表实现 它的Entry对象是无序排序的,Key值和value值都可以为null 但是一个HashMap只能有一个kay值为null的映射(key值不可重复)

    介绍了HashMap类的概念 那怎么创建呢?  代码如下:

    //导入包
    import java.util.HashMap;
    //创建Hashmap
    HashMap hash = new HashMap();

    那HashMap类中有什么常用方法呢?如下:

    get(Object key); 指定健获取所映射的值
    Clear();从此映射中移除所有的映射关系
    remove(Object key);从此映射中移除指定键的映射关系(如果存在)
    size();  获取此映射中的键-值映射的关系
    put(K key,V value) 在此映射中关联指定的值与指定键  如果该映射以前包含了一个该键的映射关系  从而达到修改的功能
    entrySet 语法: public Set<Map.Entry<K,V>> enttryset()  返回map中所有的键值对
    KeySet  语法: public Ste<k>keyset()  返回此映射中所包含的键的set视图
    getKey()  获取键 
    getValue() 获取值

    如何向HashMap中添加映射关系呢?如下:

    //创建HashMap
    HashMap hashmap =  new HashMap();
    //通过HashMap类的Put()方法添加映射关系
    hashmap.put(1, "张三");

    这里需要注意的是:1.向HashMap中添加映射关系时  需要指定一个Key(键)指定一个Value(值)从而达到映射关系,

                                     2.同样这里的健(key)和值(value)都是object类型,

    如何获取HashMao中的数据呢?HashMap是键值对可以通过获取键的方法获取数据代码如下:

    //通过HashMap类的gat(object key)获取值
    System.out.println(hashmap.get(1));

    那如何遍历HashMap中的元素呢? 用foreach迭代器实现 代码如下:

    //遍历HashMap的Key值获取数据
    for (Object item:hashmap.keySet()) {
        System.out.println(hashmap.get(item));
                
    }

    其他的方法就不一一测试了  ( ̄▽ ̄)~* 

    那现在有一个问题 比如如下代码:

    List list = new ArrayList();
    list.add("qqyumidi");
    list.add("corn");
    list.add(100);
     for (int i = 0; i < list.size(); i++) {
           String name = (String) list.get(i); //1
           System.out.println("name:" + name);
    }

    定义了一个List类型的集合,先向其中加入了两个字符串类型的值,随后加入一个Integer类型的值。这是完全允许的,因为此时list默认的类型为Object类型。在之后的循环中,由于忘记了之前在list中也加入了Integer类型的值或其他编码原因,很容易出现类似于//1中的错误。因为编译阶段正常,而运行时会出现“java.lang.ClassCastException”异常。因此,导致此类错误编码过程中不易发现。

    以上代码中有两个问题:

    A.当我们将一个对象放入集合中,集合不会记住此对象的类型,当再次从集合中取出此对象时,改对象的编译类型变成了Object类型,但其运行时类型任然为其本身类型。

    B.因此,//1处取出集合元素时需要人为的强制类型转化到具体的目标类型,且很容易出现“java.lang.ClassCastException”异常。

    那有什么办法可以使集合能够约束元素类型呢 并达到安逸不报错呢?在Collection和Map中有出现了一个泛型集合。

    3.什么是泛型?

    泛型也可以理解为“参数化类型”,类型的参数化,就是可以把类型像方法的参数那样传递。这一点意义非凡。

    那它有什么作用呢? :泛型使编译器可以在编译期间对类型进行检查以提高类型安全,减少运行时由于对象类型不匹配引发的异常。

    怎么定义个泛型集合呢?把上面的代码修改如下:

    List<String> list = new ArraysList<String>();//定义泛型的语法 
    
    list.add("aaa");
    
    list.add("bbb");
    
    list.add(1111);//1
    
    foreach(String item : list){
    
       System.out.println(item);    
    
    }

    根据上面的代码 得到 定义泛型集合的语法:

    List<E> list  = new ArraysList<E>();
    在List<>尖括号里是要对集合数据类型的约束
    <E>中的E表示类型形参,可以接收具体的类型实参
    上面的代码集合类型是String类型 那么代码“1”我们添加一个int类型的数据 这样编译器是会报错的,因为在定义泛型的时候 限制的是String类型 所以只能添加String类型的数据,
    所以我们总结: 当泛型进行了数据类型约束的时候 不能添加其他的数据类型,否则编译器会报错。
    那么HashSet也可以定义泛型,对元素的数据类型进行约束,那怎么创建HashSet泛型呢?语法如下:
    //创建HashSet泛型
    HashSet<E> hashSet = new HashSet<E>();

    同样是对HashSet中的元素进行数据类型约束 用法如上,具体方法 请往上看HashSet集合的方法。

    需要注意的是:

                     1.泛型集合中 不能添加泛型规定的类型及其子类型以外的对象 否则会报错
                     2.泛型集合中的限定类型 不能使用基本数据类型
                     3. 可以通过使用包装类限定允许存入的基本数据类型

    以上是Collection家族的集合和泛型,那么Map家族有泛型吗?  答案是肯定的  

    HashMap如何定义泛型呢  我们用代码实现一下  代码如下:

    //定义HashMap泛型
    HashMap<K, V> Hashmap = new HashMap<K, V>();

    在HashMap<K,V>

    K代表的是Key(键)的数据类型,

    V代表的值(value)的数据类型,

    也就是说 K键的数据类型必须是规定的数据类型不能是其他的数据类型,值(value)也是一样。

    以上是对泛型的介绍,这里在介绍一下Map中的contains方法:

    contains方法 某个序列是否包含某个对象  如果包含则返回true  如果不包含则返回faslse

    HashMap中:

    ContainsKey(object key); 获取此映射是否包含对于指定建的映射关系
    ContainsValue(object values); 获取此映射是否在此映射中存在的值

    具体怎么使用呢?请看代码:

    Student类

    public class Student {
        //学号
        private String id;
        
        //姓名
        private String name;
        
        
        public String getId() {
            return id;
        }
    
    
        public void setId(String id) {
            this.id = id;
        }
    
    
        public String getName() {
            return name;
        }
    
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Student(String id,String name){
            
            this.id=id;
            this.name=name;
            
        }
        
    
    }

    test类

    import java.util.HashMap;
    /**
     * ClassName: TestContains 
     * @Description: TODO测试 Map接口的HashMap类的Contains方法
    */
    public class TestContains {
        
        public static void main(String[] args) {
            
            //创建HashMap泛型   键的类型约束是String类型 值的类型约束是学生类(Student)
            HashMap<String, Student> hashmap  = new HashMap<String, Student>();
            //创建一个学生 张三
            Student zs = new Student("A1000", "张三");
            //向泛型中添加元素
            hashmap.put("1",zs);
            //检查是否存在键Key 1
            boolean yesno = hashmap.containsKey("1");
            //输出结果
            System.out.println("Does it contain key1:"+yesno);
            //检查是否包含值 Value “张三”这个学生
            boolean yesno1 = hashmap.containsValue(zs);
            //输出结果
            System.out.println("Does it contain values‘张三’:"+yesno1);
            
        }
    }

    这里我的HashMap中key的约束数据类型是String (这里大家注意下 泛型类型约束不能放基本数据类型 可以放数据类型的类 )value的类型约束是Student类的实例,也是就是说我定义的是学生类  里面只能放一个学生 要是放一个老师就不行。

    言归正传 这里我使用HashMap中的Contains方法来判断泛型中是否包含某个键 或者包含某个对象,它的返回值类型就是Boolean类型,true或false;

    接下来带大家认识两个接口和一个工具类:

    1.Collections(工具类)

    Collections工具类是java集合框架中 用来操作集合对象的工具类,这里我们只介绍一个方法sort();

    在使用之前需要导入工具类的包 代码如下:

    //导入包
    import java.util.Collections;

    sort()方法呢主要是排序 语法如下:

    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;
    public class TetsCollectionsSort {
        public static void main(String[] args) {
            
            //创建ArrayList泛型
            List<String> list = new ArrayList<String>();
            //向集合里添加数据
            list.add("aasd");
            list.add("csfgsfd");
            list.add("zasd");
            list.add("gghg");
            //输出排序前
            System.out.println("排序前");
            for (String item : list) {
                System.out.println(item);
            }
            //进行排序
            Collections.sort(list);
            //排序后
            System.out.println("排序后");
            for (String item : list) {
                
                System.out.println(item);
                
            }
        }
    }
    这里发现这些字符串的顺序发生了变化 那么是怎么进行排序的呢?
    答:
    在排序String字符串的时候是比较首字母排序   如果首字母一样则比较第二个字符  如此往下,如果字符串的开头是数字,则比较数字的大小,数字在前,字母在后,
    上面是java集合框架的Collections工具类的sort()方法的介绍,下面介绍一个接口
    2.Comparable接口
    前面介绍了Collections.sort()方法   而要实现序列的排序就要实现comparable接口下面就介绍Comparable接口
    实现该接口表示,这个类的实例可以进行自然排序,
    定义了默认的比较规则
    其实现类需要compareTo()方法
    compareTo
    ()方法返回整数表示大 负数表示小 0表示相等
    一个生活的小案例 在学校里做广播体操时 一般学生的排列都是按照身高去排列,从矮到高排列 因此学生是可以进行比较的,那么我们想两个事物要进行比较,是不是要找到可以比较的方式呢?在我们比较连个事物的时候
    会有一个默认的比较规则,称为自然排序,比如在学生排列的时候这个身高就是可以比较的特性,也是默认的比较规则,那么自然顺序就是身高之间的差异。
    那么如何用代码实现呢? 代码如下:
    Student类
    public class Student{
        //学号
        private String id;
        
        //姓名
        private String name;
        
        
        public String getId() {
            return id;
        }
    
    
        public void setId(String id) {
            this.id = id;
        }
    
    
        public String getName() {
            return name;
        }
    
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Student(String id,String name){
            
            this.id=id;
            this.name=name;
            
        }
    }
    test类
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Collections;
    
    /* ClassName: TestContains 
     * @Description: TODO测试comparable接口比较对象
     */
    public class TestContains {
    
        public static void main(String[] args) {
    
            // 创建HashMap泛型 键的类型约束是String类型 值的类型约束是学生类(Student)
            List<Student> list = new ArrayList<Student>();
            // 创建两个学生 张三 李四
            Student zs = new Student("Z1000", "张三");
            Student ls = new Student("V1000", "李四");
            // 向集合中添加元素
            list.add(zs);
            list.add(ls);
            // 排列前
            for (Student item : list) {
                System.out.println("学号是:" + item.getId() + "姓名:" + item.getName());
            }
            // 排列
            Collections.sort(list);//1
            // 排序后
            for (Student item : list) {
                System.out.println("学号是:" + item.getId() + "姓名:" + item.getName());
            }
    
        }
    }

    这里呢我们的代码1处会报错的  是因为咱们的Student这个类没有实现comparable接口  所以我们要对Student这个类进行改造 修改后的代码如下:

    public class Student  implements Comparable<Student>{
        //学号
        private String id;
        
        //姓名
        private String name;
        
        
        public String getId() {
            return id;
        }
    
    
        public void setId(String id) {
            this.id = id;
        }
    
    
        public String getName() {
            return name;
        }
    
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Student(String id,String name){
            
            this.id=id;
            this.name=name;
            
        }
    
      //重写comparable的comparato()方法
        @Override
        public int compareTo(Student o) {
            
            return this.id.compareTo(o.id);
        }
        
    
    }

    这里让Student这个类实现Comparable接口  因为接口都是抽象的 所以这里必须重写compareTo()方法  

    这个方法实现  让学生的Id进行一个比较排列 返回整形  那么Test类输出如下:

    排序前
    学号是:Z1000姓名:张三
    学号是:V1000姓名:李四
    排序后
    学号是:V1000姓名:李四
    学号是:Z1000姓名:张三

    这里的排序方法向上面介Collections.sort()方法一样

    3.Comparator接口 ---- 比较工具
    用于定义临时比较规则,而不是默认比较规则
    其实现类需要实现Compare()方法
    强行对某个对象 collection 进行整体排序 的比较函数。可以将 Comparator 传递给 sort 方法
    compare()方法返回整数表示大 负数表示小 0表示相等

    具体实现comparator接口的代码如下:
    StudentComparator类
    import java.util.Comparator;
    
    public class StudentComparator implements Comparator<Student>{
    
      //要实现Comparator接口必须要重写Compare()方法 @Override
    public int compare(Student o1, Student o2) { //按照学生的姓名进行排列 return o1.getName().compareTo(o2.getName()); } }
    Test类修改如下:
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Collections;
    
    /* ClassName: TestContains 
     * @Description: TODO测试comparable接口比较对象和comparator接口
     */
    public class TestContains {
    
        public static void main(String[] args) {
    
            // 创建HashMap泛型 键的类型约束是String类型 值的类型约束是学生类(Student)
            List<Student> list = new ArrayList<Student>();
            // 创建两个学生 张三 李四
            Student zs = new Student("Z1000", "张三");
            Student ls = new Student("V1000", "李四");
            // 向集合中添加元素
            list.add(zs);
            list.add(ls);
            // 排列前
            System.out.println("排序前");
            for (Student item : list) {
                System.out.println("学号是:" + item.getId() + "姓名:" + item.getName());
            }
            // 排列
            Collections.sort(list);
            // 排序后
            System.out.println("排序后");
            for (Student item : list) {
                System.out.println("学号是:" + item.getId() + "姓名:" + item.getName());
            }
            //按照姓名排序如下
            System.out.println("按照姓名排序是:");
            Collections.sort(list,new StudentComparator());
            for (Student item : list) {
                System.out.println("学号是:" + item.getId() + "姓名:" + item.getName());
            }
            
        }
    }

    这里Collections.sort();时需要传递一个集合  和一个实现类的对象,

    本章主要介绍Java集合框架的主要成员有:Collection接口  Map接口 Collections工具类  Comparable接口 Comparator接口

    本章内容到此结束!!!

     




     

  • 相关阅读:
    Oracle 数值函数
    oracle常用函数
    LeetCode Second Highest Salary 第二高薪水
    placeholder在不同浏览器下的表现及兼容方法
    鼠标放在图片上指针变成放大镜形状
    PS如何查找自己想要的字体
    网页常用字体
    JS倒计时代码
    JavaScript 导出Excel 代码
    event.keycode大全(javascript)
  • 原文地址:https://www.cnblogs.com/zkdayup/p/7737529.html
Copyright © 2020-2023  润新知