首页 > 编程语言 >【老白学 Java】泛型应用 - 卡拉 OK(三)

【老白学 Java】泛型应用 - 卡拉 OK(三)

时间:2024-12-21 21:58:16浏览次数:11  
标签:Comparable Java String Song ArrayList 泛型 OK public

泛型应用 - 卡拉 OK(三)

码老白
文章来源:《Head First Java》修炼感悟。

上文说到,正当老白为编译错误焦头烂额时,事情有了转机。老白在 API 中找到了答案,终于弄清楚了 v3.0 编译错误的原因。 为了以后不会忘记,特地在这里留下记录方便随时翻看。

一、原来是泛型惹的「祸」

为了保证集合中数据安全,Java 5.0 后续版本增加了泛型特性,防止不同类型数据被放到同一个集合中。

先来看看 API 中关于 ArrayList 的定义:
ArrayList类定义可以看到,ArrayList 类声明使用了 <E> 这种方式来表示泛型,意思就是在创建列表对象时把 E 换做实际类型。比如前面我们使用 new 创建的 Song 列表对象,其实原型应该是这样的:


public class ArrayList<Song> extends AbstractList<Song> implements List<Song>, ...

再看看 ArrayList 的 add() 方法定义:
ArrayList的add方法ArrayList 的 add() 方法同样使用了泛型,所以创建 Song 类型的列表只允许添加 Song 类型对象。

二、泛型应该这样用

其实 Collections.sort() 方法多处使用了泛型,来看看定义:
sort方法定义可以看到,Collections 的泛型被直接声明在 sort() 方法中,与 ArrayList 声明在类中有些不同。 sort() 声明使用 <T extends ...> 这样的方式表示 T 类型必须是继承自指定对象,这样做的目的就是对传入的方法参数进行严格限制,进一步保证数据类型安全。

sort() 的参数为 List<T>,方法描述中明确指出 T 必须实现 Comparable 接口。 Comparable 接口只有一个方法,来看看定义:
Comparable接口方法方法说明
对当前对象和指定对象进行排序比较。如果当前对象小于、等于或大于指定对象时,分别返回负整数、零或正整数。

也就是说,Song 需要实现 Comparable 接口才能进行对比操作。

三、Song 实现 Comparable 接口

我们再来看看 v3.0 代码,很明显问题就出在下面这段代码中:

public void go() {
	loadSongs();
	System.out.println(tracks);

	// 曲目排序
	Collections.sort(tracks);
	System.out.println(tracks);
}

tracks 是一个 ArrayList 对象,保存了所有 Song 类型元素,因为 Song 对象没能实现 Comparable 接口,不满足 Collections.sort() 的声明,自然也就不会存在 compareTo() 方法,所以必然会报错。解决方式也很简单,只要实现接口就可以了。

接下来老白再次修改 Song:

/**
 * 文件:Song.java
 *
 * 描述:歌曲信息类,用于保存歌曲名称、歌手等信息,
 * 		并且实现了 Comparable 接口用于按曲目排序。
 * 版本:v4.0
 */
public class Song implements Comparable<Song> {
	
	// 定义歌曲信息
	String title;
	String artist;
	String rating;
	String bpm;

	// 默认构造方法
	public Song() {}

	// 构造器,新建对象时传入歌曲信息
	public Song(String t, String a, String r, String b) {
		title = t;
		artist = a;
		rating = r;
		bpm = b;
	}
	
	// 实现接口方法
	// 返回负值、0 或者正数,表示小于,等于或者大于
	public int compareTo(Song s) {
		return title.compareTo(s.getTitle());
	}
	
	// 返回歌曲名称
	public String getTitle() {
		return title;
	}

	// 返回歌手名称
	public String getArtist() {
		return artist;
	}

	// 返回歌曲等级
	public String getRating() {
		return rating;
	}

	// 返回歌曲节拍
	public String toString() {
		return title;
	}
}

还记得那次的编译错误吧,当初传入 String 可以通过编译,而传入 Song 就会报错。 那是因为 String 已经实现了 Comparable 接口:
String实现接口所以排序的流程就是,Collections.sort() 调用 Song 类中的 compareTo() 方法,而 Song 类的 compareTo() 会自动调用 String 类的 compareTo() 方法,并返回一个整数来决定谁更靠前。

尝试再次编译:
v4.0编译成功OK,编译成功,并且正确排序。

迎接新挑战

解决了按歌名排序的问题后,老白兴致不减,开始思考另一个问题:若是按照歌手名称排序又该如何做? 老白决定趁热打铁,准备去做这件事情。


《 上一篇 泛型应用 - 卡拉 OK(二)下一篇 泛型应用 - 卡拉 OK(四) 》

标签:Comparable,Java,String,Song,ArrayList,泛型,OK,public
From: https://blog.csdn.net/liujun_sdn/article/details/144593923

相关文章

  • 【老白学 Java】泛型应用 - 卡拉 OK(四)
    泛型应用-卡拉OK(四)文章来源:《HeadFirstJava》修炼感悟。上文说到,解决了按歌名排序的问题后,老白立刻想到了按歌手名字排序的问题。老白决定趁热打铁,尝试着实现自定义排序方式。Collections的另一种排序老白查看了Collections另一个排序方法的定义,对参与比较的......
  • javaFX.(蜜雪冰城点餐小程序)MySQL数据库
    学习Java只有3个月,不喜勿喷该小程序是用的MySQL数据库,编辑软件用的equals,为什么不用idea有提示因为主打一个纯手打要源码私信目录javafx.小程序(蜜雪冰城点餐系统)简介主体思路思路讲解用户登录用户注册忘记密码​编辑主页个人信息修改冬日温暖活动模糊查询,商品......
  • javaweb练习分析——4
    对于单表的查询可能会有多种,其中较为简单的是查询所有、根据id查询、根据其他单一条件查询,但有时会遇到相较于前面的操作较为复杂的操作,就是多条件查询。需要根据前端页面输入的条件来查询。对比简单的查询操作第一个区别是用注解不在适用,要在mapper.xml文件中书写sql语句<sele......
  • javaweb练习分析——5
    在完成对单表的增删改查操作后,就要实现项目中的业务逻辑,比如登录操作、还有目前这个项目中的房产之间的买卖业务逻辑,需要不同角色之间共同完成功能,将多表联系起来。以顾客购买房产为例,第一步首先要将在售的房产呈现出来,之后就是顾客可以点击地址查看详细信息,然后顾客点击交易可以......
  • javaweb练习分析——3
    先实现简单的对各个单表之间的增删改查的操作就以增加数据为例,由于比较简单,就可以直接用注解的方式来实现在mapper文件中,书写sql语句@Insert("insertintohouseinfovalues(#{houseId},#{roomType},#{address},#{year},#{area},#{sales},#{status},#{agent},#{customer})")......
  • JavaSwing 菜单栏
    try{BeautyEyeLNFHelper.frameBorderStyle=BeautyEyeLNFHelper.FrameBorderStyle.osLookAndFeelDecorated;//UIManager.put("RootPane.setupButtonVisible",false);org.jb2011.lnf.beautyeye.BeautyEyeLNFHelpe......
  • Java实现贪吃蛇游戏
    目录一、项目结构二、实现步骤1.创建Snake类2.创建Food类3.创建GameBoard类4.创建SnakeGame类三、总结贪吃蛇是一个经典的电子游戏,它的玩法非常简单,但又充满了挑战。玩家通过控制蛇的移动,吃到食物并不断成长,目标是尽可能长时间生存。本文将介绍如何使用J......
  • 深入理解 JavaScript 中的闭包:让你的代码更简洁高效
    深入理解JavaScript中的闭包:让你的代码更简洁高效JavaScript中的闭包是一个常见且强大的概念,许多JavaScript开发者都在工作中频繁使用闭包。虽然闭包听起来有些抽象,但一旦理解它的工作原理,它将成为你代码中不可或缺的工具。本文将通过简单易懂的解释,结合实际例子,帮助......
  • java微服务中使用redis做缓存技术的应用场景介绍和代码实现
    在Java微服务架构中,Redis作为一种高性能的内存数据结构存储系统,常被用作缓存技术。Redis支持多种数据结构(如字符串、哈希、列表、集合、有序集合等),并且提供了丰富的命令集和高效的读写性能,非常适合用于缓存场景。以下是Redis在Java微服务中的常见应用场景及其代码实现示例。1.......
  • Java学习笔记
    面向过程小知识点基本类型变量和引用类型变量局部变量和成员变量成员变量分为:静态成员变量和实例成员变量staticfinal修饰的成员变量称为常量(宏替换)多态使用父类类型的引用指向子类的对象该引用只能调用父类中定义的方法和变量如果子类中重写了父类中的一个方法,那么在调......