Java比较器
导语
本节内容,比较器Comparable是核心内容。
主要内容
- 重新认识Arrays类
- 两种比较器的使用
具体内容
Arrays类
在之前一直使用的“java.util.Arrays.sort()”可以实现数组的排序,而Arrays类就是java.util包中提供的一个工具类,这个工具类主要是完成所有与数组有关的操作功能。
在这个类里面存在有二分查找法:public static int binarySearch(数据类型[] a, 数据类型 key)。但是如果要进行二分查找,有一个前提,那么就是数组必须是排序后的内容。
范例:实现二分查找
public class TestDemo {
public static void main(String args[]) {
int data [] = new int [] {1, 5, 6, 2, 3, 4, 9, 8, 7, 10};
java.util.Arrays.sort(data); // 进行排序
System.out.println(Arrays.binarySearch(data, 9));
}
}
输出结果
8
Arrays类提供了数组比较:public static boolean equals(数据类型[] a, 数据类型[] a2),只不过借用了equals的方法名称,与Object类的equals()没有关系。
范例:实现二分查找
public class TestDemo {
public static void main(String args[]) {
int dataA [] = new int [] {1, 2, 3};
int dataB [] = new int [] {2, 1, 3};
int dataC [] = new int [] {1, 2, 3};
System.out.println(Arrays.equals(dataA, dataB));
System.out.println(Arrays.equals(dataA, dataC));
}
}
输出结果
false ture
要想判断数组是否相同,需要顺序完全一致。
- 填充数组:public static void fill(数据类型[] a, 数据类型 val)。
- 将数组变为字符串输出:public static String toString(数据类型[] a)。
范例:使用上面方法
public class TestDemo {
public static void main(String args[]) {
int data[] = new int[10];
Arrays.fill(data, 3);
System.out.println(Arrays.toString(data));
}
}
输出结果
[3, 3, 3, 3, 3, 3, 3, 3, 3, 3]
以上实际上就属于数组的基本操作,只不过这样的操作在实际的开发里面很少出现。
比较器:Comparable(核心)
下面来观察一下Arrays类中提供的数组排序方法:public static void sort(Object[] a)。
发现Arrays类里面可以直接利用sort()方法实现对象数组排序。
范例:编写测试代码
public class Book {
private String title;
private double price;
public Book(String title, double price) {
this.title = title;
this.price = price;
}
public String to String() {
return "书名:" + this.title + " 价格:" + this.price;
}
}
public class TestDemo {
public static void main(String args[]) {
Book books [] = new Book [] {
new Book("Java开发", 79.8),
new Book("JSP开发", 69.8),
new Book("Oracle开发", 99.8),
new Book("Android开发", 89.8),
};
Arrays.sort(books); // 对象数组排序
System.out.println(Arrays.toString(books));
}
}
输出结果
Exception in thread "main" java.lang.ClassCastException:Book cannot be cast to java.lang.Comparable...
造成此类异常只有一个原因:丙个没有关系的类对象发生了强制性的转换。
每一个对象实际上只保留有地址信息,地址里面是有内容的,所以如果是普通的int型数组要进行比较,只要判断大小就够了,但是如果是对象数组,里面包含的如果只是编码(地址)比较是没意义的,就拿上面的代码来讲,应该按照价格排序才是有意义的,所以此处必须要明确地设置出比较的规则:
比较的规则就是由Comparable接口定义的,此接口定义如下:
public interface Comparable<T> {
public int compareTo(T o);
}
实际上String类就是Comparable接口的子类,之前使用的compareTo()方法就是比较的操作功能,如果用户现在要针对于对象进行比较,建议compareTo()方法返回三类数据:1(大于)、0(等于)、-1(小于)。
范例:使用比较器
/**
* Java学习交流QQ群:589809992 我们一起学Java!
*/
public class Book implements Comparable<Book> { // 实现比较
private String title;
private double price;
public Book(String title, double price) {
this.title = title;
this.price = price;
}
@Override
public String to String() {
return "书名:" + this.title + " 价格:" + this.price;
}
@Override
public int compareTo(Book o) { // Arrays.sort()会自动调用此方法比较
if(this.price > o.price) {
return 1;
} else if(this.price < o.price) {
return -1;
} else {
return 0;
}
}
}
public class TestDemo {
public static void main(String args[]) {
Book books [] = new Book [] {
new Book("Java开发", 79.8),
new Book("JSP开发", 69.8),
new Book("Oracle开发", 99.8),
new Book("Android开发", 89.8),
};
Arrays.sort(books); // 对象数组排序
System.out.println(Arrays.toString(books));
}
}
输出结果
[书名:JSP开发 价格:69.8, 书名:Java开发 价格:79.8, 书名:Android开发 价格:89.8, 书名:Oracle开发 价格:99.8]
compareTo()方法由Arrays.sort()自动进行调用。
以后不管何种情况下,只要是一组对象要排序,对象所在的类一定要实现Comparable接口。
挽救的比较器:Comparator
Comparable接口的主要特征是在类定义的时候就默认实现好的接口,那么如果说现在有一个类已经开发完善了。
但是由于初期的设计并没有安排此类对象数组的排序,而后又突然需要实现对象数组的排序,那么这个时候,在不能修改Book类定义的情况下是不能使用Comparable接口的,为此,在Java里面为了解决这个问题,在Java里又出现了另一个比较器:java.util.Comparator。
原本在Comparator接口下有两个方法:
@FunctionalInterface
public interface Comparator<T> {
public int compare(T o1, T o2);
public boolean equals(Object obj);
}
而真正要实现的只有compare()方法,需要单独准备出一个类来实现Comparator接口,这个类将作为指定类的排序类。
范例:定义排序的工具类
public class BookComparator implements Comparator<Book> {
@Override
public int compare(Book o1, Book o2) {
if(o1.getPrice() > o2.getPrice()) {
return 1;
} else if(o1.getPrice() < o2.getPrice()) {
return -1;
} else {
return 0;
}
}
}
之前使用Comparable接口的时候利用的是Arrays类中的sort()方法,可是现在更换了一个接口之后,那么可以使用另外一个被重载的sort()方法:public static <T> void sort(T[] a, Comparator<? super T> c)。
范例:实现排序
public class TestDemo {
public static void main(String args[]) {
Book books [] = new Book [] {
new Book("Java开发", 79.8),
new Book("JSP开发", 69.8),
new Book("Oracle开发", 99.8),
new Book("Android开发", 89.8),
};
Arrays.sort(books, new BookComparator()); // 对象数组排序
System.out.println(Arrays.toString(books));
}
}
输出结果:
[书名:JSP开发 价格:69.8, 书名:Java开发 价格:79.8, 书名:Android开发 价格:89.8, 书名:Oracle开发 价格:99.8]
使用Comparator比较麻烦,因为要定义一个专门的排序类,而且调用排序的时候也要明确的指明一个排序规则类。
面试题:请解释Comparable和Comparator的区别。
- 如果对象数组要进行排序那么必须设置排序规则,可以使用Comparable或Comparator接口实现。
- java.lang.Comparable是在一个类定义的时候要去实现好的接口,这样本类的对象数组就可以进行排序,在Comparable接口下定义有一个public int compareTo()方法。
- java.util.Comparator是专门定义一个指定类的比较规则,属于挽救的比较操作,里面有两个方法:compare()、equals()。
总结
不管何种情况下,只要牵扯到对象数组的排序大多数使用Comparable接口。
Java学习交流QQ群:589809992 我们一起学Java!
Java比较器的更多相关文章
- Java比较器对数组,集合排序一
数组排序非常简单,有前辈们的各种排序算法,再加上Java中强大的数组辅助类Arrays与集合辅助类Collections,使得排序变得非常简单,如果说结合比较器Comparator接口和Collato ...
- java比较器Comparable接口和Comaprator接口
Comparable故名思意是比较,意思就是做比较的,然后进行排序. 1.什么是comparable接口 此接口强行对实现它的每个类的对象进行整体排序.此排序被称为该类的自然排序 ,类的 compar ...
- 黑马----JAVA比较器:Comparable和Comparator
黑马程序员:Java培训.Android培训.iOS培训..Net培训 一.Comparable接口 1.public interface Comparable{ public int compare ...
- java比较器Comparator 使用
PresonDemo package cn.stat.p5.person.demo; public class PresonDemo implements Comparable { private S ...
- java比较器 之compareable 和comparato比较
compareable 测试类import java.util.Set; import java.util.TreeSet; public class Test { public static voi ...
- Java 比较器
比较器 Arrays 类 主要功能: 完成所有与数组有关的操作的工具类 二分查找: 在一个有序的数字序列中进行二分查找 public static int binarySearch(数据类型 [] a ...
- TreeSet的两种实现方法:Comparable和Comparator(Java比较器)
Comparable与Comparator实际上是TreeSet集合的两种实现方式,用来实现对象的排序.下边介绍一下两种比较器的使用方法和区别. Comparable称为元素的自然顺序,或者叫做默认顺 ...
- 小白养成记——Java比较器Comparable和Comparator
一.使用情景 1. 调用Arrays.sort()方法或Collections.sort()方法对自定义类的对象排序 以Arrays.sort()为例.假定有如下自定义的Person类 1 publ ...
- java比较器Comparator
1. 实现比较类 public class Comparator implements java.util.Comparator<TaskInfo>{ @Override public i ...
随机推荐
- 学习python的*args和 **kwargs
*args表示任何多个无名参数,它是一个tuple(元组):**kwargs表示关键字参数,它是一个dict(字典) def foo(*args, **kwargs): print 'args = ' ...
- CSS display使用
.今天我们来分析一下display的一些用法,display样式在我们整个CSS设置中,非常重要,掌握好display,才能有效的解决CSS布局的问题,在理解display之前,我们先了解两个概念:块 ...
- chrome开发工具指南(十)
检查和删除 Cookie 从 Application 面板检查和删除 Cookie. TL;DR 查看与 Cookie 有关的详细信息,例如名称.值.网域和大小,等等. 删除单个 Cookie.选定网 ...
- Linq 实现sql中的not in和in条件查询
T-SQL的IN: Select ProductID, ProductName, CategoryID From dbo.Products Where CategoryID in (1, 2) T-S ...
- 日期时间范围选择插件:daterangepicker使用总结
分享说明: 项目中要使用日期时间范围选择对数据进行筛选;精确到年月日 时分秒;起初,使用了layui的时间日期选择插件;但是在IIE8第一次点击会报设置格式错误;研究了很久没解决,但能确定不是layu ...
- AFN和SDWebImage请求网络图片的一点问题
问题1.AFN 处理有关图片相关的请求的问题 在使用AFN Post网络图片的时候发现NSLocalizedDescription=Request failed: unacceptable conte ...
- STEP 7-MicroWIN SMART 西门子PLC再次安装问题
我的电脑第一次安装s7(STEP 7-MicroWIN SMART 西门子PLC)是没有问题的,有一次不小心删除,再次安装却怎么也安装不上.猫那个咪的!Why! 网上各种查资料,完全不能解决问题,有的 ...
- C 语言 define 变参__VA_ARGS__使用
在C语言的标准库中,printf.scanf.sscanf.sprintf.sscanf这些标准库的输入输出函数,参数都是可变的.在调试程序时,我们可能希望定义一个参数可变的输出函数来记录日志,那么用 ...
- 团队作业4——第一次项目冲刺(Alpha版本) 2
一.Daily Scrum Meeting照片 二.燃尽图 三.项目进展 1.完成了大部分查重算法的书写. 余弦查重算法 2.其他非主页面的部分设计. 查重过程的显示页面 四.困难与问题 1.算法是程 ...
- 【Beta】 第一次Daily Scrum Meeting
一.本次会议为第一次meeting会议 二.时间:20::0AM-20:50AM 地点:宿舍楼下 三.会议站立式照片 四.今日任务安排 成员 昨日任务 今日任务 林晓芳 对已完成的功能进行进一步测 ...