zoukankan      html  css  js  c++  java
  • 第十七天

    java里的数据类型中,number数据类型,比如intdouble还有字符串类型Stirng等等,都是能够比较大小的,为什么?原因就是他们都实现了一个接口就是Comparable接口,现实的应用中我们可能会遇到想让自定义的类的对象可以进行排序,前提就是需要这里类的对象能比较大小,怎么办?

     

    接口Comparable

    我们知道数字是可以用> < == 等运算符进行比较大小的,其实在字符串中也有CompareTo方法,这个方法可以用于比较字符串大小的,根据字典顺序进行排序。

    Str1.compareTo(Str2);

    其返回的是一个int类型值。若Str1等于参数字符串Str2字符串,则返回0;若该Str1按字典顺序小于参数字符串Str2,则返回值小于0;若Str1按字典顺序大于参数字符串Str2,则返回值大于0

     

    Java中很多类也都有CompareTo方法,甚至于排序算法的底层也是依赖于比较的,而这个比较就是依赖于各种数据类型的CompareTo或者Compare方法。Java中所有的compareTo方法都源于一个接口,那就是Comparable。这个接口只有一个方法,那就是CompareTo。所有想要具有比较功能的类,都建议实现这个接口,而非是自己定义这个功能,这是面向对象的概念(将具有相同功能的事物抽象到一个共同的类或接口),并且为了多态也建议通过实现接口来进行向上转型,通过接口来操作具体实现,这也是面向接口编程要求我们做的。下面我们来具体了解一下Comparable接口。

     

    先分析一下Strnig类的compareToequals方法:

     

    package coursetest;
    
    public class Person implements Comparable<Person> {
        private Integer id;//建议做成id的包装类
        private String name;//定义字符串类型变量 变量名为name    
        private int age;//定义int整型变量 变量名为age
         //为三个私有变量构造get set方法 使数据可以在私有的情况赋值和取出
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        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;
        }
          //重写compareTo方法 
        @Override
        public int compareTo(Person o) {//根据id比大小
            // p1.compartTo(p2);
            //p1>p2:正整数,p1==p2:0;p1<p2:负整数
    //        if(this.id>o.id) return 1;
    //        if(this.id==o.id) return 0;
    //        return 1;
            return this.id - o.id; //一句话搞定上面三行代码
        }
      //重写hashCode方法
        @Override
        public int hashCode() {//重写hashCode
            // TODO Auto-generated method stub
            return id.hashCode();
        }
        //重写equals方法,提供自定义的相等标准   参数名为obj
        @Override
        public boolean equals(Object obj) {
            if(obj instanceof Person) {    //是否obj变量类型可以转换为Person变量类型
                Person other =(Person)obj;//强制转换,就是将obj类型强制转换成Person类型
                if (this.id == other.id) {
                    return true;
                }else {
                    return false;
                }
            }
            return false;
        }
       //重写toString方法
        @Override
        public String toString() {
            return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
        }
    //重写toString() 可以理解为是对对象在打印输出时候的一种格式化。这样做符合业务逻辑,显示结果人性化   
    }
    package coursetest;
    
    import java.util.Arrays;
    
    public class Demo {
        public static void main(String[] args) {
            Person p1 = new Person();//对象1
            p1.setId(1);
            Person p2 = new Person();//对象2
            p2.setId(2);
            Person p3 = new Person();//对象3
            p3.setId(3);
            Person p4 = new Person();//对象4
            p4.setId(4);
            
            Person [] arr = new Person [] {p4,p3,p1,p2};//定义一个数组,将对象1234放入
            System.out.println(Arrays.toString(arr));//打印数组
            Arrays.sort(arr);//调用array.sort方法为数组排序
            System.out.println(Arrays.toString(arr));//再次打印数组
        }
    }

    注意:一般情况下,compareToequals方法应该是统一的,equals返回truecompareTo应用返回0;所以实现了compareTo方法就要覆盖equals方法,让两者保持一致!而且前面又讲了覆盖equals方法,就一定要重写hashCode方法。

    最后compareable接口,我们自定义一个Person类来实践一下!

    定义要给Person类,实例化5Person类的对象,放到数组里,然后用Arrays.sort(数组);工具对数组进行排序! 

    接口Comparator

    1. 我们需要控制某个类的次序,而该类不支持排序(即没有实现Comparable接口)。那么,我们可以创建一个该类的比较器,这个比较器只需要实现Comparator。若一个类实现了Comparator接口,则它一定要实现compare(T o1,T o2)方法,但不一定要实现equals(Object obj)方法;

    2. 如果类的设计师没有考虑到Compare的问题而没有实现Comparable接口,可以通过Comparator来实现比较算法进行排序;为了使用不同的排序标准做准备,比如:升序、降序

    在上面的例子基础上,使用一些接口Comparator,然后用Arrays.sort(数组,比较器);对数组排序输出一下!

     

    public class Dog {
        private Integer id;//建议做成id的包装类
        private String name;//定义字符串类型变量 变量名为name    
        private int age;//定义int整型变量 变量名为age
        //下面为三个私有变量的get set方法
        public Integer getId() {
            return id;
        }
        public void setId(Integer id) {
            this.id = id;
        }
        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;
        }
        //覆盖toString方法
        @Override
        public String toString() {
            return "Dog [id=" + id + ", name=" + name + ", age=" + age + "]";
        }    
    }
    package coursetest;
    
    import java.util.Comparator;
    
    public class DogComparetor2 implements Comparator<Dog>{
         //覆盖compare方法
        @Override
        public int compare(Dog o1, Dog o2) {
            
            return o1.getAge() - o2.getAge();//两个对象的年龄差
        }
    }
    package coursetest;
    
    import java.util.Comparator;
    
    public class DogComparetor2 implements Comparator<Dog>{
         //覆盖compare方法
        @Override
        public int compare(Dog o1, Dog o2) {
            
            return o1.getAge() - o2.getAge();//两个对象的年龄差
        }
    }
    package coursetest;
    
    import java.util.Arrays;
    
    public class Demo {
        public static void main(String[] args) {
            Dog dog1 = new Dog();
            dog1.setId(1);
            dog1.setAge(2);
            Dog dog2 = new Dog();
            dog2.setId(2);
            dog2.setAge(5);
            Dog dog3 = new Dog();
            dog3.setId(3);
            dog3.setAge(1);
            Dog[] arr = new Dog[] { dog2, dog1, dog3 };// 定义一个数组,将对象123放入
            System.out.println(Arrays.toString(arr));// 打印数组
            //进行Id排序
            Arrays.sort(arr,new DogComparetor());//调用自己创建的DogComparetor比较器
    //Arrays.sort(arr,new DogComparetor2());
    //调用自己创建的DogComparetor2比较器进行年龄排序
            System.out.println(Arrays.toString(arr));// 打印数组
        }
    }

    CompareableComparator两者比较总结:

    1. 前者应该比较固定,和一个具体类相绑定,而后者比较灵活,它可以被用于各个需要比较功能的类使用

    2. Comparable是排序接口;若一个类实现了Comparable接口,就意味着该类支持排序;而Comparator是比较器;我们若需要控制某个类的次序,可以建立一个该类的比较器来进行排序。

    3. Comparable相当于内部比较器,而Comparator相当于外部比较器

    4. Comparable是通用的接口,用户可以实现它来完成自己特定的比较,而Comparator可以看成是一种算法的实现,在需要容器集合实现比较功能的时候,来指定这个比较器,这可以看成是一种设计模式,将算法和数据分离。

     

     

     

     

     

     

    java7里面新增的Objects类,该类的主要用途是将操作对象的一切常用操作进行的封装。包括hashCodeequals等。 java87的基础上又新增一些方法。

    知识点一:Objects类简介

    本类由一些操作对象的静态工具方法构成,这些工具方法包括了非空检查方法的非空参数检查比较对象的hashCode为对象返回一个字符串比较两个对象

    知识点二:Objects特点

    1.该类是使用final修饰,不能被继承 2.该类的构造方法被私有化(使用private修饰),不能直接创建对象 3.该类中所有的方法都是静态方法,可以使用类型直接调用(对应2,该类不需要创建对象)

    知识点三:Objects内方法介绍

    //比较两个对象是否相等(首先比较内存地址,然后比较a.equals(b),只要符合其中之一返回true

    public static boolean equals(Object a, Object b);

     

    //深度比较两个对象是否相等(首先比较内存地址,相同返回true;如果传入的是数组,则比较数组内的对应下标的值是否相同)

    public static boolean deepEquals(Object a, Object b);

    import java.util.Arrays;
    import java.util.Objects;
    
    public class Demo {
        public static void main(String[] args) {
            Integer [] a1 = new Integer [] {1,2,3};
            Integer [] a2 = new Integer [] {1,2,3};
            Integer [] a3 = new Integer [] {1,3,3};
            System.out.println(Objects.deepEquals(a1, a2));//true
            System.out.println(Objects.deepEquals(a1, a3));//false        
        }
    }

    //返回对象的hashCode,若传入的为null,返回0

    public static int hashCode(Object o);

    import java.util.Objects;
    
    public class Demo {
        public static void main(String[] args) {
            String string = "a";
            String s1 = null;
            System.out.println(string.hashCode());//97
            //System.out.println(s1.hashCode());//java.lang.NullPointerException报异常
            System.out.println(Objects.hashCode(s1));//0
        }

    //返回传入可变参数的所有值的hashCode的(加工后)总和(这里说总和有点牵强,具体参考Arrays.hashCode()方法)

    public static int hash(Object... values);

    public class Demo {
        public static void main(String[] args) {
        System.out.println("a".hashCode());//97
        System.out.println(Objects.hashCode("a"));//97
        System.out.println(Objects.hash("a"));//128
        }
    }

    1. 

    //返回对象的String表示,若传入null,返回null字符串

    public static String toString(Object o)

     

    import java.util.Objects;
    
    public class Demo {
        public static void main(String[] args) {
        String s = "aaa";
        System.out.println(s.toString());//aaa
        System.out.println(Objects.toString(s));//aaa
        String s1 = null;
        //System.out.println(s1.toString());//报错
        System.out.println(Objects.toString(s1));//null
        }
    }

    //返回对象的String表示,若传入null,返回默认值nullDefault

    public static String toString(Object o, String nullDefault)

    import java.util.Objects;
    
    public class Demo {
        public static void main(String[] args) {
        String s = null;
        System.out.println(Objects.toString(s,"default"));//default
        }
    }

    //使用指定的比较器c 比较参数a和参数b的大小(相等返回0a大于b返回整数,a小于b返回负数)

    public static <T> int compare(T a, T b, Comparator<? super T> c)

     

    //如果传入的objnull抛出NullPointerException,否者返回obj

    public static <T> T requireNonNull(T obj)

     

    //如果传入的objnull抛出NullPointerException并可以指定错误信息message,否者返回obj

    public static <T> T requireNonNull(T obj, String message)

    import java.util.Objects;
    
    public class Demo {
        public static void main(String[] args) {
        String s = null;
        Objects.requireNonNull(s,"不能为空");
        }
    }

    //判断传入的obj是否为null,是返回true,否者返回false

    public static boolean isNull(Object obj)

     

    //判断传入的obj是否不为null,不为空返回true,为空返回false(和isNull()方法相反)

    public static boolean nonNull(Object obj)

     

    //如果传入的objnull抛出NullPointerException并且使用参数messageSupplier指定错误信息,否者返回obj

    public static <T> T requireNonNull(T obj, Supplier<String> messageSupplier)

     

    知识点五:总结

    Objects类给我们提供了一些常用的操作对象的方法,我们可以直接使用,这是非常方便的。尤其是requireNonNull()方法, 在我们写方法时需要判断传入的参数是否为null可以使用该方法及其方便。

     

     

     

     

     

     

     

     

     

     

    java里的数据类型中,number数据类型,比如intdouble还有字符串类型Stirng等等,都是能够比较大小的,为什么?原因就是他们都实现了一个接口就是Comparable接口,现实的应用中我们可能会遇到想让自定义的类的对象可以进行排序,前提就是需要这里类的对象能比较大小,怎么办?

     

    接口Comparable

    我们知道数字是可以用> < == 等运算符进行比较大小的,其实在字符串中也有CompareTo方法,这个方法可以用于比较字符串大小的,根据字典顺序进行排序。

    Str1.compareTo(Str2);

    其返回的是一个int类型值。若Str1等于参数字符串Str2字符串,则返回0;若该Str1按字典顺序小于参数字符串Str2,则返回值小于0;若Str1按字典顺序大于参数字符串Str2,则返回值大于0

     

    Java中很多类也都有CompareTo方法,甚至于排序算法的底层也是依赖于比较的,而这个比较就是依赖于各种数据类型的CompareTo或者Compare方法。Java中所有的compareTo方法都源于一个接口,那就是Comparable。这个接口只有一个方法,那就是CompareTo。所有想要具有比较功能的类,都建议实现这个接口,而非是自己定义这个功能,这是面向对象的概念(将具有相同功能的事物抽象到一个共同的类或接口),并且为了多态也建议通过实现接口来进行向上转型,通过接口来操作具体实现,这也是面向接口编程要求我们做的。下面我们来具体了解一下Comparable接口。

     

    先分析一下Strnig类的compareToequals方法:

     

    注意:一般情况下,compareToequals方法应该是统一的,equals返回truecompareTo应用返回0;所以实现了compareTo方法就要覆盖equals方法,让两者保持一致!而且前面又讲了覆盖equals方法,就一定要重写hashCode方法。

     

    最后compareable接口,我们自定义一个Person类来实践一下!

    定义要给Person类,实例化5Person类的对象,放到数组里,然后用Arrays.sort(数组);工具对数组进行排序!

     

     

    接口Comparator

    1. 我们需要控制某个类的次序,而该类不支持排序(即没有实现Comparable接口)。那么,我们可以创建一个该类的比较器,这个比较器只需要实现Comparator。若一个类实现了Comparator接口,则它一定要实现compare(T o1,T o2)方法,但不一定要实现equals(Object obj)方法;

    2. 如果类的设计师没有考虑到Compare的问题而没有实现Comparable接口,可以通过Comparator来实现比较算法进行排序;为了使用不同的排序标准做准备,比如:升序、降序

     

    在上面的例子基础上,使用一些接口Comparator,然后用Arrays.sort(数组,比较器);对数组排序输出一下!

     

     

    CompareableComparator两者比较总结:

    1. 前者应该比较固定,和一个具体类相绑定,而后者比较灵活,它可以被用于各个需要比较功能的类使用

    2. Comparable是排序接口;若一个类实现了Comparable接口,就意味着该类支持排序;而Comparator是比较器;我们若需要控制某个类的次序,可以建立一个该类的比较器来进行排序。

    3. Comparable相当于内部比较器,而Comparator相当于外部比较器

    4. Comparable是通用的接口,用户可以实现它来完成自己特定的比较,而Comparator可以看成是一种算法的实现,在需要容器集合实现比较功能的时候,来指定这个比较器,这可以看成是一种设计模式,将算法和数据分离。

     

     

     

     

  • 相关阅读:
    SQLServer2008安装卡在publishing assembly information
    找新朋友
    如何解决:Android中 Error generating final archive: Debug Certificate 的错误
    Open your mind
    A+B Format (20)
    A+B
    1005. Spell It Right (20)
    如何彻底卸载 SQL SERVER
    VC快捷键
    C#之将数据导出到Excel
  • 原文地址:https://www.cnblogs.com/jikebin/p/12623010.html
Copyright © 2011-2022 走看看