菜鸡的Java笔记 comparator 比较器
1.数组操作类: Arrays
2.两种比较器的使用: Comparable Comparator
3.实现二叉树算法
content (内容)
1.数组操作类: Arrays
Arrays 类一早就开始使用了。最早使用的是它的排序操作,但是现在打开 Arrays 观察一下有那些方法
二分查找法: public static int binarySearch(数据类型[] a,数据类型 key)
数组比较: public static boolean equals(数据类型[] a,数据类型[] a2)
数组的填充: public static void fill(数据类型[] a,数据类型 val)
数组转换为String输出: public static String toString(数据类型[] a)
范例:二分查找
package cn.mysterious.study3; import java.util.Arrays; public class StudyComparator { public static void main(String[] args) {
// TODO Auto-generated method stub
int data [] = new int[]{1,29,93,44,55,666,7,788,99};
java.util.Arrays.sort(data);
System.out.println(Arrays.binarySearch(data, 7));
} }
范例:数组比较
package cn.mysterious.study3; import java.util.Arrays; public class StudyComparator { public static void main(String[] args) {
// TODO Auto-generated method stub
int dataA [] = new int[]{1,29,93,44,55,666,7,788,99};
int dataB [] = new int[]{1,29,93,44,55,666,7,788,99};
System.out.println(Arrays.equals(dataA, dataB));
} }
范例:数组填充
package cn.mysterious.study3; import java.util.Arrays; public class StudyComparator { public static void main(String[] args) {
// TODO Auto-generated method stub
int data [] = new int[]{1,29,93,44,55,666,7,788,99};
Arrays.fill(data, 10);
System.out.println(Arrays.toString(data));
} }
在 Arrays 类中几乎包含了所有可能使用到的数组相关操作 重要的是这些方法的原理因为面试题或面试上会问到
2.比较器: Comparable
在 Arrays 类中提供有一个方法: public static void sort(Object[] a)
此方法可以直接针对对象数组进行排序的操作
但是如果现在真的要进行对象数组的排序,并不是意味着直接调用次方法即可
如果直接调用就有可能出现如下的错误信息:
Exception in thread "main" java.lang.ClassCastException:
cn.mysterious.study3.Person cannot be cast to java.lang.Comparable
之所以造成这样的问题,是因为如果要想进行对象数组的排序,必须要解决数据大小关系的问题,然而对象无法区分出大小关系
那么为了解决这样的问题 java 会自动的在排序的时候将所有的对象强制转换为 Comparable 接口对象
也就是说如果要想实现对象数组的自动排序,那么对象所在的类一定要实现 Comparable 接口
public interface Comparable<T>{
public int compareTo(T o)
}
String 累中的 comparaTo() 方法本身就是覆写了 Comparable 接口中的 comparaTo() 方法,而如果说用户现在需要进行排序
实际上只需要返回三个内容即可:0,-1,1
范例:对象数组的排序实现
package cn.mysterious.study3; import java.util.Arrays;
class Person implements Comparable<Person>{
private String name;
private int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "姓名:" + this.name + ",年龄:" + this.age + "\n";
}
@Override
public int compareTo(Person o) {
// TODO Auto-generated method stub
if (this.age > o.age) {
return 1;
}else if(this.age < o.age){
return -1;
}else {
return 0;
}
// 简化操作: return this.age - o.age;
}
}
public class StudyComparator { public static void main(String[] args) {
Person per[] = new Person[]{
new Person("小少爷",15),
new Person("大少爷",35),
new Person("二少爷",28),
};
Arrays.sort(per);
System.out.println(Arrays.toString(per));
} }
结论:以后不管何种情况下,只要是进行对象数组的排序,一定要使用 Comparable 接口完成
实现二叉树算法( Binary Tree ,(简称:BT) )
二叉树也好,链表也好,本质是一样的,目的就是为了保存数据,实现动态的对象数组
所有的数据结构都一定有一个前提:必须痛过节点来进行数据的包裹,目的:确定先后顺序
那么现在也对 Node 进行修改,让其可以保存对象( Object Comparable ),但是现在每个节点上要保留有两个子节点:左子树,右子树
保存的原则:比根节点小的数据放在左子树,比根节点大于等于的数据保存的右子树
最后按照中序遍历(左-根-右)的方式可以取得内容,所以数据是排序后的结果
范例:实现基础的二叉树 StudyTwoForkTree
package cn.mysterious.study3;
import java.util.Arrays;
class Person implements Comparable<Person>{
private String name;
private int age;
public Person(String name,int age){
this.name = name;
this.age = age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "姓名:" + this.name + ",年龄:" + this.age + "\n";
}
@Override
public int compareTo(Person o) {
return this.age - o.age;
}
}
class BinaryTree{ // 二叉树的实现类
private class Node{ // 数据结构中必须有 Node 类,负责保存数据以及节点的关系匹配
@SuppressWarnings(value = "rawtypes")
private Comparable data;
private Node left;//比根节点小的内容
private Node rigth;//比根节点大或等于的内容
@SuppressWarnings("unused")
public Node( @SuppressWarnings("rawtypes") Comparable data){
this.data = data;
}
@SuppressWarnings("unchecked")
public void addNode(Node newNode) {
// TODO Auto-generated method stub
if (this.data.compareTo(newNode.data) > 0) { // 保存在左边
if (this.left == null) {
this.left = newNode;
}else {
this.left.addNode(newNode);
}
}else {
if (this.rigth == null) {
this.rigth = newNode;
} else {
this.rigth.addNode(newNode);
}
}
}
public void toArrayNode() {
// TODO Auto-generated method stub
if (this.left != null) {// 有左节点
this.left.toArrayNode();
}
BinaryTree.this.retData[BinaryTree.this.foot ++] = this.data;
if (this.rigth != null) {
this.rigth.toArrayNode();
}
}
}
//****** 编写 BinaryTree 的操作 ******
private Node root; //必须保留根节点
private int count = 0;
private int foot = 0;
private Object[] retData;
@SuppressWarnings("rawtypes")
public void add(Object obj) { //数据的追加
Comparable data = (Comparable)obj;
Node newNode = new Node(data);// 将数据包装在 Node 节点之中
if (this.root == null) {
this.root = newNode;
}else {
this.root.addNode(newNode);
}
this.count ++;
}
public Object[] toArray(){
if (this.count > 0) {
this.foot = 0;
this.retData = new Object[this.count];
this.root.toArrayNode();
return this.retData;
} else {
return null;
}
}
}
public class StudyTwoForkTree { public static void main(String[] args) {
BinaryTree bt = new BinaryTree();
bt.add(new Person("小少爷",15));
bt.add(new Person("大少爷",35));
bt.add(new Person("二少爷",28));
System.out.println(Arrays.toString(bt.toArray()));
} }
如果想收入高一些的可以适当的把代码写的完善一些
比较器: Comparator
通过 Comparable 的观察可以发现,如果一个类的对象要想进行对象数组排序,那么这个类在定义的时候就必须明确的实现好 Comparable 接口
但是有没有这样一种可能性出现,一个类原本定义完成了,原本是没有排序要求的,可是后期却需要追加排序,并且这个类已经不能够修改了
那么在这种情况下,就可以利用另外一个接口完成排序: java.util.Comparator 接口
此接口定义如下:
@FunctionalInterface
public interface Comparator<T>{
public int compare(T o1,T o2)
public boolean equals(Object obj)
}
如果要想继续使用 Arrays 实现排序操作,那么就必须观察新的排序方法:
排序: public static <T> void sort(T[] a,Comparator<? super T> c)
范例:定义一个单独的 Person 类
class Person {
private String name;
private int age;
public Person(){}
public Person(String name,int age){
this.name = name;
this.age = age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "姓名:" + this.name + ",年龄:" + this.age + "\n";
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
}
前提: Person 类不允许发生改变
范例:实现单独的比较器
package cn.mysterious.study3; import java.util.Comparator; class Person {
private String name;
private int age;
public Person(){}
public Person(String name,int age){
this.name = name;
this.age = age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "姓名:" + this.name + ",年龄:" + this.age + "\n";
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public String getName() {
return name;
}
}
class PersonComparator implements Comparator<Person>{
@Override
public int compare(Person o1, Person o2) {
// TODO Auto-generated method stub
return o1.getAge() - o2.getAge();
}
}
public class ComparatorClass {
public static void main(String[] args) {
Person per[] = new Person[]{
new Person("小少爷",15),
new Person("大少爷",35),
new Person("二少爷",28),
};
Arrays.sort(per,new PersonComparator()); // 编写排序
System.out.println(Arrays.toString(per));
}
}
面试题:请解释两种比较器的区别?
在进行对象数组排序的过程之中需要使用到比较器,比较器有两个: Comparator Comparable
java.util.Comparable :是在类定义的时候默认实现好的接口。里面提供有一个 comparaTo() 方法用于比较大小
java.util.Comparator :需要单独定义一个排序的比较规则类,里面有两个方法: compare(),equals()
总结
以后如果开发中考虑到排序的需求,优先考虑使用 Comparable 接口,不到万不得已不要使用 Comparator
菜鸡的Java笔记 comparator 比较器的更多相关文章
- 菜鸡的Java笔记 - java 断言
断言:assert (了解) 所谓的断言指的是在程序编写的过程之中,确定代码执行到某行之后数据一定是某个期待的内容 范例:观察断言 public class Abnorma ...
- 菜鸡的Java笔记 - java 正则表达式
正则表达式 RegularExpression 了解正则表达式的好处 正则表达式的基础语法 正则表达式的具体操作 content (内容 ...
- 菜鸡的Java笔记 数字操作类
数字操作类 Math 类的使用 Random 类的使用 BigInteger 和 BigDecimal 类的使用 Math 是一 ...
- 菜鸡的Java笔记 - java 线程常用操作方法
线程常用操作方法 线程的命名操作,线程的休眠,线程的优先级 线程的所有操作方法几乎都在 Thread 类中定义好了 线程的命名和取得 ...
- 菜鸡的Java笔记 日期操作类
日期操作类 Date 类与 long 数据类型的转换 SimpleDateFormat 类的使用 Calendar 类的使用 如 ...
- 菜鸡的Java笔记 开发支持类库
开发支持类库 SupportClassLibrary 观察者设计模式的支持类库 content (内容) 什么是观察者设计模式呢? ...
- 菜鸡的Java笔记 简单JAVA 类的开发原则以及具体实现
/* 现在要求定义一个雇员信息类 在这个类之中包含有雇员编号 姓名 职位 基本工资 佣金等信息 对于此时给定要求实际上就是描述一类事物,而这样的程序类在在java之中可以将其称为简单java类 ...
- 菜鸡的Java笔记 - java 访问控制权限
java中四种访问控制权限的使用 内容 在java里面一共定义有四个权限,按照由小到大的顺序:private<defaule<prote ...
- 菜鸡的Java笔记 国际化程序实现原理
国际化程序实现原理 Lnternationalization 1. Locale 类的使用 2.国家化程序的实现,资源读取 所谓的国际化的程序 ...
随机推荐
- The Data Way Vol.5|这里有一场资本与开源的 battle
关于「The Data Way」 「The Data Way」是由 SphereEx 公司出品的一档播客节目.这里有开源.数据.技术的故事,同时我们关注开发者的工作日常,也讨论开发者的生活日常:我们聚 ...
- 七牛云的 python sdk 是如何 批量删除资源的
今天做项目的时候用到七牛云,关于对资源的操作是在后端做的,用的SDK,但是,在网上没找到详细的解析,官方文档也没有太详细的解说,所以无奈只好看下源码 这里做一下简单的记录 from qiniu imp ...
- bzoj3073Journeys(线段树优化最短路)
这里还是一道涉及到区间连边的问题. 如果暴力去做,那么就会爆炸 那么这时候就需要线段树来优化了. 因为是双向边 所以需要两颗线段树来分别对应入边和出边 QwQ然后做就好了咯 不过需要注意的是,这个边数 ...
- 洛谷4208 JSOI2008最小生成树计数(矩阵树定理+高斯消元)
qwq 这个题目真的是很好的一个题啊 qwq 其实一开始想这个题,肯定是无从下手. 首先,我们会发现,对于无向图的一个最小生成树来说,只有当存在一些边与内部的某些边权值相同的时候且能等效替代的时候,才 ...
- Elasticsearch 中为什么选择倒排索引而不选择 B 树索引
目录 前言 为什么全文索引不使用 B+ 树进行存储 全文检索 正排索引 倒排索引 倒排索引如何存储数据 FOR 压缩 RBM 压缩 倒排索引如何存储 字典树(Tria Tree) FST FSM 构建 ...
- 腾讯bugly产生bug定位行数不准解决方案
定位不准是因为做了混淆导致行数与实际代码行数不对.解决方案是要上传符号表.下载地址https://bugly.qq.com/v2/downloads 下载好因为我打开文件的说明文件是空文件(可能工作人 ...
- UltraSoft - Beta - Scrum Meeting 6
Date: May 22n'd, 2020. Scrum 情况汇报 进度情况 组员 负责 今日进度 q2l PM.后端 修复了DDL日程自动发邮件被服务器"吞掉"的bug后端增加了 ...
- [no code][scrum meeting] Alpha 10
项目 内容 会议时间 2020-04-16 会议主题 用户管理第一版交付 会议时长 15min 参会人员 PM+后端组成员 $( "#cnblogs_post_body" ).ca ...
- Pogo-Cow S
这题出在单调队列优化dp里,就离谱好吧...... 对不住了上来先喷一波,不过离谱是确实的 dp的含义也很简单,就是说从j到i的分数最大值 直接上代马,里面说的很详细了 1 #include<b ...
- BZOJ4919[Lydsy1706月赛]大根堆-------------线段树进阶
是不是每做道线段树进阶都要写个题解..根本不会写 Description 给定一棵n个节点的有根树,编号依次为1到n,其中1号点为根节点.每个点有一个权值v_i. 你需要将这棵树转化成一个大根堆.确切 ...