【Java】泛型 之 使用泛型

2023-09-22 14:31:26

使用ArrayList时,如果不定义泛型类型时,泛型类型实际上就是 Object

// 编译器警告:
List list = new ArrayList();
list.add("Hello");
list.add("World");
String first = (String) list.get(0);
String second = (String) list.get(1);

此时,只能把<T>当作Object使用,没有发挥泛型的优势。

当我们定义泛型类型<String>后,List<T>的泛型接口变为强类型List<String>

// 无编译器警告:
List<String> list = new ArrayList<String>();
list.add("Hello");
list.add("World");
// 无强制转型:
String first = list.get(0);
String second = list.get(1);

当我们定义泛型类型<Number>后,List<T>的泛型接口变为强类型List<Number>

List<Number> list = new ArrayList<Number>();
list.add(new Integer(123));
list.add(new Double(12.34));
Number first = list.get(0);
Number second = list.get(1);

编译器如果能自动推断出泛型类型,就可以省略后面的泛型类型。例如,对于下面的代码:

List<Number> list = new ArrayList<Number>();

编译器看到泛型类型List<Number>就可以自动推断出后面的ArrayList<T>的泛型类型必须是ArrayList<Number>,因此,可以把代码简写为:

// 可以省略后面的Number,编译器可以自动推断泛型类型:
List<Number> list = new ArrayList<>();

泛型接口

除了ArrayList<T>使用了泛型,还可以在接口中使用泛型。例如,Arrays.sort(Object[])可以对任意数组进行排序,但待排序的元素必须实现Comparable<T>这个泛型接口:

public interface Comparable<T> {
    /**
     * 返回负数: 当前实例比参数o小
     * 返回0: 当前实例与参数o相等
     * 返回正数: 当前实例比参数o大
     */
    int compareTo(T o);
}
可以直接对String数组进行排序:

// sort
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        String[] ss = new String[] { "Orange", "Apple", "Pear" };
        Arrays.sort(ss);
        System.out.println(Arrays.toString(ss));

    }
}

这是因为String本身已经实现了Comparable<String>接口。如果换成我们自定义的Person类型试试:

// sort
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        Person[] ps = new Person[] {
            new Person("Bob", 61),
            new Person("Alice", 88),
            new Person("Lily", 75),
        };
        Arrays.sort(ps);
        System.out.println(Arrays.toString(ps));

    }
}

class Person {
    String name;
    int score;
    Person(String name, int score) {
        this.name = name;
        this.score = score;
    }
    public String toString() {
        return this.name + "," + this.score;
    }
}

运行程序,我们会得到ClassCastException,即无法将Person转型为Comparable。我们修改代码,让Person实现Comparable<T>接口:

// sort
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        Person[] ps = new Person[] {
            new Person("Bob", 61),
            new Person("Alice", 88),
            new Person("Lily", 75),
        };
        Arrays.sort(ps);
        System.out.println(Arrays.toString(ps));
    }
}
class Person implements Comparable<Person> {
    String name;
    int score;
    Person(String name, int score) {
        this.name = name;
        this.score = score;
    }
    public int compareTo(Person other) {
        return this.name.compareTo(other.name);
    }
    public String toString() {
        return this.name + "," + this.score;
    }
}

运行上述代码,可以正确实现按name进行排序。

也可以修改比较逻辑,例如,按score从高到低排序。请自行修改测试。

小结

使用泛型时,把泛型参数替换为需要的class类型,例如:ArrayList<String>ArrayList<Number>等;

可以省略编译器能自动推断出的类型,例如:List<String> list = new ArrayList<>();

不指定泛型参数类型时,编译器会给出警告,且只能将视为Object类型;

可以在接口中定义泛型类型,实现此接口的类必须实现正确的泛型类型。

更多推荐

性能测试 —— 性能测试常见的测试指标 !

一、什么是性能测试先看下百度百科对它的定义,性能测试是通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试。我们可以认为性能测试是:通过在测试环境下对系统或构件的性能进行探测,用以验证在生产环境下系统性能是否达到预估的性能需求,发现系统可能存在的性能瓶颈,进而改善优化并系统的性能,提高系

铁路设备屡遭破坏!RFID电子锁实现铁路防护网破坏实时报警管理

铁路防护网是铁路运输中保障安全的重要组成部分,然而,铁路设备被破坏的情况时有发生,给铁路运输带来了严重的安全隐患和经济损失。一、铁路防护网面临的挑战铁路防护网作为铁路运输的重要保障措施,时刻面临着破坏行为的威胁。传统的锁控系统存在以下问题:开关锁记录不完善:传统锁控系统无法准确记录每次开锁和关锁的时间、地点以及操作人员

Xamarin.Android实现App内版本更新

目录1、具体的效果2、代码实现2.1基本原理2.2开发环境2.3具体代码2.3.1基本设置2.3.2系统的权限授予2.3.3进度条的layout文件2.3.4核心的升级文件3、代码下载4、知识点5、参考文献1、具体的效果有事需要在程序内集成自动更新的功能,网上找了下,改改适配下Xamarin.Android,效果如下2

API接口文档管理系统平台搭建(更新,附系统源码及教程)

简介这是一款简洁大方的API接口文档管理系统,附系统源码及教程方法。可以轻松管理和使用API接口。安装步骤打开config/database.php配置数据库信息导入数据库data.sql设置运行目录为/public伪静态设置thinkPHP后台地址/admin/login.html账号:admin密码:123456源

LLM(一)| 百川智能baichuan7B、13B、53B以及baichuan2总结

之前在文章baichuan-53BVSChatGLM-6B对比中做过百川大模型53B和ChatGLM6B模型的效果对比,由于百川大模型的内测模型是53B,因此本次对比参数量差异较大,但仍然可以看到两个模型的效果。百川大模型在benchmark上有超越ChatGLM和LLaMA的迹象,尤其是在中文任务上的表现,下面分别对

让Pegasus天马座开发板吃上STM8S标准库

WeCanStudio官方仓库的示例工程,只提供基于STM8S003寄存器方式来开发Pegasus天马座开发板。在此,我将基于官方的工程示例,将STM8S标准库移植到工程中。先上图,看运行结果:main.c文件#include"config.h"#include"delay.h"#defineLED_GPIO_PORT

OpenGL之着色器

着色器(Shader)是运行在GPU上的小程序。这些小程序为图形渲染管线的某个特定部分而运行。从基本意义上来说,着色器只是一种把输入转化为输出的程序。着色器也是一种非常独立的程序,因为它们之间不能相互通信;它们之间唯一的沟通只有通过输入和输出。GLSL着色器是使用一种叫GLSL的类C语言写成的。GLSL是为图形计算量身

MyCat主从数据库集群搭建

1背景最近工作需要对比几种数据库技术方案,主从读写分离集群也是其中之一。接着上一篇文章《MySQL主从数据库搭建》基础上继续搭建MyCat主从集群。2MyCat什么是MyCat?MyCat是数据库中间件,就是介于数据库和应用之间,进行数据处理与交互的中间服务。可以对数据进行分片处理,从原有一个库,被切分为多个分片数据库

安装torch113、cuda116并运行demo【Transformer】

文章目录01.导读02.显卡驱动版本03.创建环境、下载安装必要包04.运行参考代码:01.导读安装torch113、cuda116并运行demo【Transformer】02.显卡驱动版本C:\Users\Administrator>nvidia-smi-l10WedSep1323:35:082023±-------

Docker 原理

基础技术试验进程linuxnamespaceMount(mnt)namespace可以在不影响宿主机文件系统的基础上挂载或者取消挂载文件系统了;PID(ProcessID)在一个pidnamespace中,第一个进程的pid为1,所有在此namespace中的其他进程都是此进程的子进程,操作系统级别的其他进程不需要在此

kruskal重构树

Kruskal重构树第二次学了。大致思路就是在最小生成树加边的时候,把每条边也设一个点,和他连着的两个点连边。由于最小生成树的贪心,感觉很像哈夫曼树,有性质是经过的边的长度(已经转化为点权)越向上越大/越小,取决于生成树的排序。那就可以通过倍增找不经过长度超过x的边所能走到的所有点,实际上是一直往上跳的那个子树。for

热文推荐