java基础类库——比较器(六)

比较器

1.1 数组操作类Arrays
Arrays 类一早就开始使用了,最早使用的是它的排序操作,但是现在打开Arrays类来观察下一下,有那些方法
(1)二分查找:public static int binarySearch(数据类型 a, 数据类型 key)
在进行此调用之前,数组必须按照sort(数据类型[])方法进行排序。如果没有排序,结果是未定义的。如果数组包含具有指定值的多个元素,则不能保证将找到哪个元素。

范例:二分查找

package day2;

import java.util.Arrays;

public class TestDemo {
    public static void main(String[] args) throws Exception {
      int date[] = {5,69,85,35,45,67,54,62,89,50,7,12,28};
        Arrays.sort(date);
        System.out.println(Arrays.binarySearch(date,67));//9
    }
}

(2)数组比较:public static boolean equals(数据类型[] a,数据类型[] a2)
如果两个数组以相同的顺序包含相同的元素,则它们是相等的。另外,如果两个数组引用都是null,则它们被认为是相等的 。

范例:数组比较

package day2;

import java.util.Arrays;

public class TestDemo {
    public static void main(String[] args) throws Exception {
        int dateA[] = new int[]{1,2,3};
        int dateB[] = new int[]{2,1,3};
        int dateC[] = new int[]{1,2,3};
        System.out.println(Arrays.equals(dateA,dateB));//false
        System.out.println(Arrays.equals(dateA,dateC));//true
    }
}

(3)数组填充:public static void fill(数据类型[] a,数据类型 val),将指定的 数据类型值分配给指定的数据类型 数组的每个元素。

(4)public static String toString(数据类型[] a)
返回指定数组的内容的字符串表示形式。 字符串表示由数组元素的列表组成,括在方括号( “[]” )中。 相邻的元素由字符", "分隔(逗号后跟一个空格)。 元素被转换为字符串由String.valueOf(int)。 返回"null"如果a是null。

范例:数组填充

package day2;

import java.util.Arrays;

public class TestDemo {
    public static void main(String[] args) throws Exception {
        int dateA[] = new int[]{1,2,3};
        Arrays.fill(dateA,5);
        System.out.println(Arrays.toString(dateA));
    }
}
[5, 5, 5]

在Arrays类中几乎包含了所有可能使用到的数组的相关操作。

1.2 比较器 Comparable接口
在Arrays类中提供有一个方法:public static void sort(byte[] a),此方法可以直接针对于队形数组进行排序的操作;但是如果现在真的要进行对象数组的排序,并不是意味着直接调用此方法即可。如果要想进行对象数组的排序,需要解决数据的大小关系问题,但是对象无法区分大小关系,那么为了解决这样的一个问题,java会自动在排序的时候将所有的对象强制转换为Comparable接口对象,也就是数组的自动排序,那么对象所在的类一定要实现Comparable接口,这个接口定义如下:

public interface Comparable<T> {
  public int compareTo(T o);
}

在这里插入图片描述

String 类中的compareTo()本身就是覆写了Comparable接口中的compareTo方法。而如果说下周需要进行排序,实际上只需要返回三个内容即可:0,-1,1

范例:对象数组排序

package day2;

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;
    }
    @Override
    public String toString() {
        return "姓名 :" + this.name + ",年龄:" + this.age + "\n";
    }

	/**
   @Override
    public int compareTo(Person p) {
       return this.age - p.age;
    }
	**/

    @Override
    public int compareTo(Person p) {
        if(this.age > p.age){//1升序,-1 降序
            return 1;
        }else if(this.age < p.age){
            return -1;
        }else {
            return 0;
        }
    }
}
public class TestDemo {
    public static void main(String[] args) throws Exception {
        Person person [] = new Person[]{
                new Person("张角",26),
                new Person("王怡",18),
                new Person("黎明",22)
        };
        Arrays.sort(person);
        System.out.println(Arrays.toString(person));
    }
}

[姓名 :王怡,年龄:18
, 姓名 :黎明,年龄:22
, 姓名 :张角,年龄:26
]

结论:只要是进行对象数组的排序,一定要使用Comparable接口完成。

1.3 实现二叉树算法(Binary Tree)
二叉树也好,链表也好,本质是一样的,目的就是为了保存多个数据,实现动态的对象数组。所有的数据结构都一定有一个前提:必须通过节点来进行数据的包裹,目的:确定先后顺序。那么现在也对Node进行修改,让其进行可以保存对象(Object,Comparable),但是现在每一个节点上要保留有两个子节点:左子树、右子树
保存原则:比根节点小的数据放在左子树,比根节点大于等于的数据保存在左子树。
在这里插入图片描述
最后按照中序遍历(左-根-右)的方式可以取得内容,所有数据的排序后的结果。

范例:实现二叉树

package day2;

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;
    }
    @Override
    public String toString() {
        return "姓名 :" + this.name + ",年龄:" + this.age + "\n";
    }
     @Override
     public int compareTo(Person p) {
        return this.age - p.age;
     }
}
class MyBinaryTree{//二叉树的实现类
    private class Node{//数据结构中必须有Node类,负责保存数据及节点的关系匹配
        @SuppressWarnings("rawtypes")
        private Comparable data;
        private Node left;//左子树,保存比根节点小的内容
        private Node right;//右子树,保存比根节点大或等于的内容
        @SuppressWarnings({"rawtypes","unused"})
        public Node(Comparable data){
            this.data = data;
        }
        public void addNode(Node newNode){
            if(this.data.compareTo(newNode.data) > 0){ //保存在左边
                if(this.left == null){
                    this.left = newNode;
                }else {
                    this.left.addNode(newNode);
                }
            }else {
                if(this.right == null){
                    this.right = newNode;
                }else {
                    this.right.addNode(newNode);
                }
            }
        }
        public void toArrayNode(){
            if(this.left != null){//有左节点
                this.left.toArrayNode();
            }
            MyBinaryTree.this.retData[MyBinaryTree.this.foot++] = this.data;
            if(this.right != null){//有右节点
                this.right.toArrayNode();
            }
        }
    }
    /********************* 编写BinaryTree 操作****************************/
    private Node root;//必须保留着根节点
    private int count = 0 ;//保存节点个数
    private Object[] retData;
    private int foot = 0;
    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 TestDemo {
    public static void main(String[] args) throws Exception {
        MyBinaryTree mbt = new MyBinaryTree();
        mbt.add( new Person("张角",26));
        mbt.add( new Person("王怡",18));
        mbt.add( new Person("黎明",22));
        mbt.add( new Person("李思",15));
        System.out.println(Arrays.toString(mbt.toArray()));
    }
}
[ 姓名 :李思,年龄:15
, 姓名 :王怡,年龄:18
, 姓名 :黎明,年龄:22
, 姓名 :张角,年龄:26
]

1.4 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 void sort(T[] a,int fromIndex,int toIndex, Comparator<? super T> c)

范例:定义一个单独的Person类(不允许Person类发生改变)

class Person{
    private String name;
    private int age;
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "姓名 :" + this.name + ",年龄:" + this.age + "\n";
    }
    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;
    }

}

范例:实现单独的比较器

package day2;

import java.util.Arrays;
import java.util.Comparator;

class PersonComparator implements Comparator<Person> {
    @Override
    public int compare(Person o1, Person o2) {
        return o1.getAge() - o2.getAge();
    }
}
public class TestDemo {
    public static void main(String[] args) throws Exception {
        Person person [] = new Person[]{
                new Person("张角",26),
                new Person("王怡",18),
                new Person("黎明",22)
        };
        Arrays.sort(person,new PersonComparator());//编写排序
        System.out.println(Arrays.toString(person));
    }
}
[姓名 :王怡,年龄:18
, 姓名 :黎明,年龄:22
, 姓名 :张角,年龄:26
]

面试题:请解释两种比较器的区别
(1)在进行对象数组排序的过程中需要使用到比较器,比较器有两个:Comparable、Comparator
(2)java.lang.Comparable:是在类定义的的时候默认实现好的接口,里面提供有一个compateTo()方法用于大小比较;
(3)java.util.Comparator需要单独定义一个排序的比较规则类,里面有两个方法:compare()、equals()。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值