Java核心API-泛型

集合框架与泛型



前言

使用Map存取数据,掌握泛型的使用,Collections的使用


一、Map接口与HashMap类

Map接口专门处理键值映射数据的存储,可以根据键实现对值的操作

最常用的实现类是HashMap

HashMap常用方法

在这里插入图片描述

二、遍历Map集合

1)通过迭代器Iterator实现遍历

2)增强for循环

3)键值对

public static void main(String[] args) {

        // 准备容器
        HashMap hashMap = new HashMap();

        // 调用方法将字符串类型的键和值存储在集合中
        hashMap.put("CN", "中国");
        hashMap.put("USA", "美国");
        hashMap.put("UK", "英国");
        hashMap.put("RU", "俄罗斯");
        hashMap.put("JP", "日本");

        // 获取集合中元素个数
        System.out.println("集合中元素个数:" + hashMap.size()); // 集合中元素个数:5
        // 判断集合是否为空
        System.out.println("集合为空:" + hashMap.isEmpty()); // 集合为空:false

        /*
         * HashMap集合存储数据,例如存储身份证号码和姓名,存储唯一,无序的对象,用键值更加便捷
         * 集合框架不同就根据需求选择应用
        */

        // 获取集合中的某一个元素,根据键来获取值
        Object obj1 = hashMap.get("CN");
        String value1 = (String) obj1;
        System.out.println(value1); // 中国

        Object obj2 = hashMap.get("USA");
        String value2 = (String) obj2;
        System.out.println(value2); // 美国

        System.out.println("------ ------ ------");

        // 遍历Map集合:因为要获取值,需要通过键来获取,所以先获取所有的键,然后遍历键去获取值
        // Set<k> keySet():返回此映射中包含的键的Set视图
        Set keySet = hashMap.keySet();
        // 遍历keySet集合,一个一个的取出里面的键
        for (Object objKey : keySet) {
            String key = (String) objKey;
            // 根据键获取值
            Object objValue = hashMap.get(key);
            String value = (String) objValue;
            System.out.println(key + "---" + value);
        }
        // 输出结果
        // USA---美国
        // RU---俄罗斯
        // UK---英国
        // JP---日本
        // CN---中国

        System.out.println("------ ------ ------");

        // 获取了所有的键之后,可以使用迭代器遍历键的集合
        /*
         * boolean hasNext()如果仍有元素可以迭代,则返回 true
         * E next()返回迭代的下一个元素
         */
        Iterator keyIterator = keySet.iterator();
        while (keyIterator.hasNext()) {
            Object objKey = keyIterator.next();
            String key = (String) objKey;
            // 根据键获取值
            Object objValue = hashMap.get(key);
            String value = (String) objValue;
            System.out.println(key + "---" + value);
        }

        System.out.println("------ ------ ------");

        // 直接从Map集合中遍历键值对
        // keyValue集合中存储的是Map里面的键值对数据,这个键值对数据的类型为Map.Entry
        Set keyValue = hashMap.entrySet();
        for (Object object : keyValue) {
            // 键值对的类型转换为起真实类型Map.Entry
            Map.Entry me = (Map.Entry) object;
            // 使用me对象调用方法获取键值对里的键
            Object keyObj = me.getKey();
            String key = (String) keyObj;
            // 使用me对象调用方法获取键值对里的值
            Object valueObj = me.getValue();
            String value = (String) valueObj;
            System.out.println(key + "---" + value);
        }

    }
}
public class HashMapDemo02 {
    public static void main(String[] args) {

        // 准备容器
        HashMap hashMap = new HashMap();

        // 调用方法将字符串类型的键和值存储在集合中
        hashMap.put("CN", "中国");
        hashMap.put("USA", "美国");
        hashMap.put("UK", "英国");
        hashMap.put("RU", "俄罗斯");
        hashMap.put("JP", "日本");

        // 获取集合中元素个数
        System.out.println("集合中元素个数:" + hashMap.size()); // 集合中元素个数:5

        // 移除JP
        Object obj1 = hashMap.remove("JP");
        System.out.println("移除JP对应的国家是:" + obj1); // 移除JP对应的国家是:日本

        // 获取集合中的元素个数
        System.out.println("集合中元素个数:" + hashMap.size()); // 集合中元素个数:4

        System.out.println("------ ------ ------");

        // 获取集合中所有的值
        Collection values = hashMap.values();
        // 遍历values集合可以使用增强for循环或迭代器
        for (Object object : values) {
            String value = (String) object;
            System.out.println(value);
        }
        // 输出结果
        // 美国
        // 俄罗斯
        // 英国
        // 中国

        System.out.println("------ ------ ------");

        // 判断集合中是否包含指定的键
        System.out.println("集合中包含JP这个键:" + hashMap.containsKey("JP")); // 集合中包含JP这个键:false
        System.out.println("集合中包含RU这个键:" + hashMap.containsKey("RU")); // 集合中包含RU这个键:true

        // 判断集合中是否包含指定的值
        System.out.println("集合中包含日本国这个值:" + hashMap.containsValue("日本")); // 集合中包含日本国这个值:false
        System.out.println("集合中包含俄罗斯联邦这个值:" + hashMap.containsValue("俄罗斯")); // 集合中包含俄罗斯联邦这个值:true
        
    }
}
public class Student {

    private String name;
    private char gender;

    public Student() {
    }

    public Student(String name, char gender) {
        this.name = name;
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

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

    public char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", gender=" + gender +
                '}';
    }
}
public class HashMapDemo01 {

    public static void main(String[] args) {

        // 准备数据:创建3个Student对象
        Student student1 = new Student("张三", '男');
        Student student2 = new Student("李四", '男');
        Student student3 = new Student("如花", '男');

        // 准备容器,存储Student对象
        HashMap hashMap = new HashMap();

        // 将数据存储到集合中
        hashMap.put("Jack", student1);
        hashMap.put("Bob", student3);
        hashMap.put("lisa", student2);

        // 获取英文名称Bob的学员信息
        Object value = hashMap.get("Bob");
        System.out.println(value); // Student{name='如花', age=30007}
        // toString()方法Object类中的方法,查看该方法的原码知道
        // 该方法输出的是兑现在内存中的地址值,我们可以在子类中对该方法进行重写,输出对象的属性信息
        System.out.println(value.toString());
        // 如果只需要获取学员对象的姓名,只能通过Student类对象调用getName()方法,value对象不能调用Student类中的getName()方法
        Student stu = (Student) value;
        System.out.println("Bob对应的学员姓名:" + stu.getName()); // Bob对应的学员姓名:如花

        System.out.println("------ ------ ------");

        // 使用增强for循环遍历所有学员的姓名
        Set keys = hashMap.keySet();
        // 遍历keys集合
        for (Object object : keys) {
            // 将键转换为真实类型String
            String key = (String) object;
            // 根据键获取值
            Object objValue = hashMap.get(key);
            // 将值转换为真实的类型Student
            Student student = (Student) objValue;
            System.out.println(key + "-" + student.getName());
        }

        System.out.println("------ ------ ------");

        // 使用迭代器循环遍历所有学员的姓名
        Iterator keyIterator = keys.iterator();
        while (keyIterator.hasNext()) {
            Object objkey = keyIterator.next();
            String key = (String) objkey;
            // 根据键获取值
            Object objValue = hashMap.get(key);
            Student student = (Student) objValue;
            System.out.println(key + "-" + student.getName() + "-" + student.getGender());
        }

        System.out.println("------ ------ ------");

        // 使用键值对遍历所有学员的姓名
        Set keyValues = hashMap.entrySet();
        for (Object object : keyValues) {
            // 键键值对的类型转换为真实类型Map.Entry
            Map.Entry me = (Map.Entry) object;
            // 获取键
            Object objKey = me.getKey();
            // 将键转换为真实类型String
            String key = (String) objKey;
            // 获取值
            Object objValue = me.getValue();
            // 将值转换为真实类型Student
            Student student = (Student) objValue;
            System.out.println(key + "-" + student.getName());
        }

    }
}

三、泛型集合

问题:如何解决以下强制类型转换时容易出现的异常问题

1)List的get(int index)方法获取元素

2)Map的get(Object key)方法获取元素

3)Iterator的next()方法获取元素

解答:通过泛型

在JDK5.0中使用泛型改写了集合框架中的所有接口和类

1、泛型的概念

将对象的类型作为参数,指定到其他类或方法上,从而保证类型转换的安全性和稳定性

本质是参数化类型

2、泛型集合

泛型集合可以约束集合内的元素类型

典型泛型集合ArrayList<>、HashMap<K,V>

1)<>、<K,V>表示该泛型集合中的元素类型

2)泛型集合中的数据不再转换为Object

除了指定了集合中的元素类型外,泛型集合和之前学习的集合用法完全一样

package javaapidemo0125.demo04;

public class Student {

    private String name;
    private char gender;

    public Student() {
    }

    public Student(String name, char gender) {
        this.name = name;
        this.gender = gender;
    }

    public String getName() {
        return name;
    }

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

    public char getGender() {
        return gender;
    }

    public void setGender(char gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", gender=" + gender +
                '}';
    }
}
package javaapidemo0125.demo04;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class HashMapDemo01 {

    public static void main(String[] args) {

        // 创建3个Student对象
        Student student1 = new Student("张三", '男');
        Student student2 = new Student("李四", '男');
        Student student3 = new Student("如花", '女');

        // 准备容器,存储上面3个Student类对象
        // HashMap hashMap = new HashMap();
        // 使用泛型
        HashMap<String, Student> hashMap = new HashMap<String, Student>();

        // 将数据存储到集合中
        hashMap.put("Jack", student1);
        hashMap.put("Bob", student2);
        hashMap.put("Lisa", student3);

        // 获取英文名为Bob的学员信息
        /*Object object = hashMap.get("Bob");
        System.out.println(object); // Student{name='李四', gender=男}
        Student s1 = (Student)object; // 向下转型
        System.out.println(s1); // Student{name='李四', gender=男}
        System.out.println(s1.toString()); // Student{name='李四', gender=男}
        System.out.println(s1.getName()); // 李四
        System.out.println(s1.getGender()); // 男*/

        // 使用泛型
        Student student = hashMap.get("Bob");
        System.out.println(student); // Student{name='李四', gender=男}
        System.out.println(student.getName()); // 李四

        System.out.println("------ ------ ------");

        // 使用增强for循环遍历所有学员姓名
        // 遍历Map集合因为要获取值,需要通过键来获取,所以先获取所有的键,然后遍历键去获取值
        // Set<K> keySet()返回此映射中所包含的键的Set视图
        Set<String> keys = hashMap.keySet();
        // 遍历键来获取值
        for (String key : keys) {
            Student students = hashMap.get(key);
            // System.out.println(key + "-" + students);
            System.out.println(key + "-" + students.getName());
            // Bob-李四 Jack-张三 Lisa-如花
        }

        System.out.println("------ ------ ------");

        // 获取键之后使用迭代器遍历键的集合
        Iterator<String> keyIterator = keys.iterator();
        // boolean hasNext()如果仍有元素可以迭代,则返回 true
        while (keyIterator.hasNext()) {
            // E next()返回迭代的下一个元素
            String key = keyIterator.next();
            // 根据键获取值
            Student students = hashMap.get(key);
            System.out.println(key + "-" + students.getName() + "-" + students.getGender());
            // Bob-李四-男 Jack-张三-男 Lisa-如花-女
        }

        System.out.println("------ ------ ------");

        // 使用键值对遍历
        // hashMap.entrySet()是将Map中的键值对放在Set中,键值对类型是entry
        Set<Map.Entry<String, Student>> keyValues = hashMap.entrySet();
        for (Map.Entry<String, Student> me : keyValues) {
            // 获取键
            String key = me.getKey();
            // 获取值
            Student students = me.getValue();
            System.out.println(key + "-" + students.getName() + "-" + students.getGender());
            // Bob-李四-男 Jack-张三-男 Lisa-如花-女
        }

        /*
          泛型使用总结:
            没有使用泛型前,集合会将存入进去的元素都向上转型变为Object类型,那么再取出来的时候也是Object类型
            这时候需要使用向下转型,将取出来的元素转换成其真实类型,才能调用对象中特有的方法
            那么在向下转型过程中,容易出现ClassCastException(类型转换异常),当然你可以使用instanceof运算符进行类型判断,比较繁琐
            因此,可以使用泛型来明确声明集合中只能存储的数据类型(相当于将集合变成了一个长度可变的数组),这个集合中就只能存储你指定的数据类型
            你存进去的是指定的数据类型,那么取出来的也是你指定的类型,此时就不需要进行向下转型,减少向下转型过程汇总可能出现的类型转换异常
         */


    }
}

四、Collections算法类

Java集合框架将针对不同数据结构算法的实现都保存在工具类中

Collections类定义了一系列用于操作集合的静态方法

Collections类常用方法

Collections和Collection不同,前者是集合的操作类,后者是集合接口

1)sort()排序

2)binarySearch()查找

3)max()\min()查找最大值最小值

Collections排序

1)Colleciotns类可以对集合进行排序、查找和替换操作

2)实现一个类的对象之间比较大小,该类要实现Comparable接口

重写compareTo()方法

package javaapidemo0125.demo05;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;

public class CollectionsDemo01 {

    public static void main(String[] args) {

        // 创建ArrayList集合对象
        ArrayList<String> stringArrayList = new ArrayList<String>();
        // 向集合中存储数据
        stringArrayList.add("hwert1");
        stringArrayList.add("gwert2");
        stringArrayList.add("fwert3");
        stringArrayList.add("erwert4");
        stringArrayList.add("dwert5");
        stringArrayList.add("cwert6");
        stringArrayList.add("bwert7");
        stringArrayList.add("awert8");
        System.out.println("集合排序前元素顺序:");
        for (String string : stringArrayList) {
            System.out.print(string + "   ");
        }
        // sort()方法:升序排序集合中元素
        Collections.sort(stringArrayList);

        System.out.println("\n集合排序前后元素顺序:");
        for (String string : stringArrayList) {
            System.out.print(string + "   ");
        }

        System.out.println();

        /*
         binarySearch()方法查找集合中的元素,在使用此方法之前,要求对集合中的元素进行升序排序,否则无法保证查询结果的正确性
         返回查找元素的下标,如果查找的元素在集合中不存在,返回一个负值
        */
        int index1 = Collections.binarySearch(stringArrayList, "awert8");
        System.out.println("qwert在集合中的位置:" + index1);

        int index2 = Collections.binarySearch(stringArrayList, "aaaaa");
        System.out.println("aaaaa在集合中的位置:" + index2);

        // max()\min()查找最大值/最小值
        String max = Collections.max(stringArrayList);
        String min = Collections.min(stringArrayList);
        System.out.println("集合中的最大值:" + max);
        System.out.println("集合中的最小值:" + min);

        // 反转集合中的元素顺序
        Collections.reverse(stringArrayList);
        System.out.println("反转集合后元素顺序:");
        for (String string : stringArrayList) {
            System.out.print(string + "   ");
        }
        
    }
}

public class Student implements Comparable<Student> {

    private String name;
    private int age;

    public Student() {
    }

    public Student(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 "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public int compareTo(Student student) {
        // 比较此对象与指定对象的顺序。如果该对象小于、等于或大于指定对象,则分别返回负整数、零或正整数
        // 根据Student类对象年龄进行排序
        if (this.getAge() < student.getAge()) {
            return -1;
        } else if (this.getAge() == student.getAge()) {
            return 0;
        } else {
            return 1;
        }
    }
}

import java.util.Collections;
import java.util.LinkedList;

public class CollectionsDemo02 {

    public static void main(String[] args) {

        LinkedList<Student> studentLinkedList = new LinkedList<Student>();

        // 创建4个Student类对象
        Student student1 = new Student("张三", 25);
        Student student2 = new Student("李四", 28);
        Student student3 = new Student("王五", 24);
        Student student4 = new Student("赵六", 26);

        // 存储数据
        studentLinkedList.add(student1);
        studentLinkedList.add(student2);
        studentLinkedList.add(student3);
        studentLinkedList.add(student4);

        // 遍历集合
        System.out.println("排序前:");
        for (Student student : studentLinkedList) {
            System.out.println(student);
        }

        System.out.println("------ ------ ------");

        // 对集合中元素进行排序
        Collections.sort(studentLinkedList);
        /*
        public static <T extends Comparable<? super T>> void sort(List<T> list)根据元素的自然顺序 对指定列表按升序进行排序
        public static <T> void sort(List<T> list,Comparator<? super T> c)根据指定比较器产生的顺序对指定列表进行排序
        java.lang 接口 Comparable<T> 类型参数:T - 可以与此对象进行比较的那些对象的类型
        int compareTo(T o) 比较此对象与指定对象的顺序
         */

        System.out.println("排序后:");
        for (Student student : studentLinkedList) {
            System.out.println(student);
        }


    }
}
  • 20
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值