Java基础复习(五):常用类及其常用方法——Object类、Scanner类、String类

常用类及其常用方法

一、Object类

Object类是所有类的主类。
    主要的方法:

1、public boolean equals(Object obj):指示一些其他对象是否等于此,用于比较2个对象的内存地址是否相等。
    (1)自反性 :对于任何非空的参考值x , x.equals(x)应该返回true 。
    (2)对称性 :对于任何非空引用值x和y , x.equals(y)应该返回true当且仅当y.equals(x)回报true 。
    (3)传递性 :对于任何非空引用值x , y和z ,如果x.equals(y)回报true个y.equals(z)回报true ,然后x.equals(z)应该返回true 。
    (4)一致性 :对于任何非空引用值x和y ,多次调用x.equals(y)始终返回true或始终返回false ,没有设置中使用的信息equals比较上的对象被修改。
    (5)对于任何非空的参考值x , x.equals(null)应该返回false 。

    注意: equals方法在非空对象上引用不会有报错可能。所以在使用时尽量保证变量不为空对象,否则会报空指针异常;如变量与字符串比较时,尽量是“字符串”.equals(变量)。通常会重写equals方法,来拥有更好的性能,比如String类对该方法进行了重写用户比较字符串的值是否相等。
    ==和equals的区别
“==”的作用:用来比较两个对象的地址值是否相等。
                       对于基本数据类型,则相当于比较数值;对于引用类型变量,则是在比较对象的地址值是否相同(即都是在比较JVM栈中的值),引用类型中存在基本数据类型的包装类这一特殊情况,由于常量池的不同,会出现不同的结果。

equals的作用:用来比较两个对象是否相等,但是不能用于比较基本数据类型的变量。
                       如果类没有重写equals()方法,则equals()方法的作用就相当于“ == ”的作用,equals()方法默认的是Objectl类中的equals()方法。如果该类重写了equals()方法,就会采用该类中的equals()方法,一般会重写为比较内容是否相等的作用,如String类中重写的equals()方法。

public class Test_equals {
    public static void main(String[] args) {
        Boolean flag;

        //基本数据类型
        int i1=300;
        int i2=300;
        flag = i1==i2;
        System.out.println("i1==i2:"+flag);
        //i1.equals(i2)会报错;

        //包装类,超过常量池的数据范围,会新建一个对象
        Integer i3=300;
        Integer i4=300;
        flag = i3==i4;
        System.out.println("i3==i4:"+flag);
        flag = i3.equals(i4);
        System.out.println("i3.equals(i4):"+flag);

        //i5创建后放入常量池,i6会从常量池中寻找再调用,所以是同一个对象
        String i5="nihao";
        String i6="nihao";
        flag = i5==i6;
        System.out.println("i5==i6:"+flag);
        flag = i5.equals(i6);
        System.out.println("i5.equals(i6):"+flag);

        //new String创建字符串时,一定会重新创建对象
        String i7=new String("nihao");
        String i8=new String("nihao");
        flag = i7==i8;
        System.out.println("i7==i8:"+flag);
        flag = i7.equals(i8);
        System.out.println("i7.equals(i8):"+flag);
    }
}

结果:
i1 == i2:true
i3 == i4:false
i3.equals(i4):true
i5 == i6:true
i5.equals(i6):true
i7 == i8:false
i7.equals(i8):true

2、public int hashCode():返回对象的哈希码值,一个int型的整数,用来确定该对象在哈希表中的索引位置。 支持这种方法是为了散列表,如HashMap提供的那样 。

        在不使用散列表(HashMap、HashSet、HashTable等数据结构上)时:其中的hasnCode()方法与equals()方法完全没有关系,hasnCode()方法没有作用。

public class Test3_HashCode {

    public static void main(String[] args) {
        // 新建2个相同内容的Person对象,
        // 再用equals比较它们是否相等
        Person p1 = new Person("eee", 100);
        Person p2 = new Person("eee", 100);
        Person p3 = new Person("aaa", 200);
        System.out.printf("p1.equals(p2) : %s; p1(%d) p2(%d)\n", p1.equals(p2), p1.hashCode(), p2.hashCode());
        System.out.printf("p1.equals(p3) : %s; p1(%d) p3(%d)\n", p1.equals(p3), p1.hashCode(), p3.hashCode());
    }

    /**
     * @desc Person类。
     */
    private static class Person {
        int age;
        String name;

        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String toString() {
            return name + " - " +age;
        }

        /**
         * @desc 覆盖equals方法
         */
        public boolean equals(Object obj){
            if(obj == null){
                return false;
            }

            //如果是同一个对象返回true,反之返回false
            if(this == obj){
                return true;
            }

            //判断是否类型相同
            if(this.getClass() != obj.getClass()){
                return false;
            }

            Person person = (Person)obj;
            return name.equals(person.name) && age==person.age;
        }
    }
}

结果:
p1.equals(p2) : true; p1(23050916) p2(32379559)
p1.equals(p3) : false; p1(23050916) p3(21282042)

        在散列表(HashMap、HashSet、HashTable等数据结构上)中使用该类:如果两个对象相等,则其hasnCode()值一定是相等的;但是如果两个对象的hasnCode()值相等,他们也不一定相等。因此在覆盖equals方法时也一定要覆盖hashCode方法。

        只重写了equals()方法:

import java.util.*;
public class Test_HashCode {

    public static void main(String[] args) {
        // 新建Person对象,
        Person p1 = new Person("eee", 100);
        Person p2 = new Person("eee", 100);
        Person p3 = new Person("aaa", 200);

        // 新建HashSet对象
        HashSet set = new HashSet();
        set.add(p1);
        set.add(p2);
        set.add(p3);

        // 比较p1 和 p2, 并打印它们的hashCode()
        System.out.printf("p1.equals(p2) : %s; p1(%d) p2(%d)\n", p1.equals(p2), p1.hashCode(), p2.hashCode());
        // 打印set
        System.out.printf("set:%s\n", set);
    }

    /**
     * @desc Person类。
     */
    private static class Person {
        int age;
        String name;

        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String toString() {
            return "("+name + ", " +age+")";
        }

        /**
         * @desc 覆盖equals方法
         */
        @Override
        public boolean equals(Object obj){
            if(obj == null){
                return false;
            }

            //如果是同一个对象返回true,反之返回false
            if(this == obj){
                return true;
            }

            //判断是否类型相同
            if(this.getClass() != obj.getClass()){
                return false;
            }

            Person person = (Person)obj;
            return name.equals(person.name) && age==person.age;
        }
    }
}

结果:
p1.equals(p2) : true; p1(23050916) p2(32379559)
set:[(eee, 100), (eee, 100), (aaa, 200)]

        由于没有重写hasnCode()方法,尽管内容相同,但是hasnCode()的值不同,所以在set集合里面还是会有重复值,equals()方法不起作用。

        重写equals()方法和hashCode()方法:

import java.util.*;
public class Test2_HashCode {

    public static void main(String[] args) {
        // 新建Person对象,
        Person p1 = new Person("eee", 100);
        Person p2 = new Person("eee", 100);
        Person p3 = new Person("aaa", 200);
        Person p4 = new Person("EEE", 100);

        // 新建HashSet对象
        HashSet set = new HashSet();
        set.add(p1);
        set.add(p2);
        set.add(p3);

        // 比较p1 和 p2, 并打印它们的hashCode()
        System.out.printf("p1.equals(p2) : %s; p1(%d) p2(%d)\n", p1.equals(p2), p1.hashCode(), p2.hashCode());
        // 比较p1 和 p4, 并打印它们的hashCode()
        System.out.printf("p1.equals(p4) : %s; p1(%d) p4(%d)\n", p1.equals(p4), p1.hashCode(), p4.hashCode());
        // 打印set
        System.out.printf("set:%s\n", set);
    }

    /**
     * @desc Person类。
     */
    private static class Person {
        int age;
        String name;

        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }

        public String toString() {
            return name + " - " +age;
        }

        /**
         * @desc重写hashCode
         */
        @Override
        public int hashCode(){
            int nameHash =  name.toUpperCase().hashCode();
            return nameHash ^ age;
        }

        /**
         * @desc 覆盖equals方法
         */
        @Override
        public boolean equals(Object obj){
            if(obj == null){
                return false;
            }

            //如果是同一个对象返回true,反之返回false
            if(this == obj){
                return true;
            }

            //判断是否类型相同
            if(this.getClass() != obj.getClass()){
                return false;
            }

            Person person = (Person)obj;
            return name.equals(person.name) && age==person.age;
        }
    }
}

结果:
p1.equals(p2) : true; p1(68545) p2(68545)
p1.equals(p4) : false; p1(68545) p4(68545)
set:[eee - 100, aaa - 200]

         比较p1和p2,hashCode()相等,且通过equals()比较它们也返回true。所以,p1和p2被视为相等。比较p1和p4,hashCode()相等;但是,通过equals()比较它们返回false。所以,p1和p4被视为不相等。equals()生效了,HashSet中没有重复元素。

3、public final native Class<?> getClass():返回此Object的运行时的类。 返回的类对象是被表示类的static synchronized方法锁定的对象。 使用了final关键字修饰,故不允许子类重写。并且需要注意的是该方法只能由类的实例变量调用。

public class Test_getClass {
    public static void main(String[] args) {
        Dog ss = new Dog();
        Class a = ss.getClass();
        System.out.println(ss.getClass());//class Dog
        System.out.println(a.getName());//Dog

    }
}

4、protected native Object clone() throws CloneNotSupportedException:用于创建并返回当前对象的一份拷贝。一般情况下,对于任何对象 x,表达式 x.clone() != x 为true,x.clone().getClass() == x.getClass() 为true。Object本身没有实现Cloneable接口,所以不重写clone方法并且进行调用的话会发生CloneNotSupportedException异常。

5、public String toString():返回类的名字@实例的哈希码的16进制的字符串。一般Object所有的子类都重写这个方法,可以自己定义输出的形式。

与多线程有关的方法:wait()、notify/notifyAll() 方法(在Java线程上再细说)
6、public final void notify():不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)。如果有多个线程在等待只会任意唤醒一个。

7、public final void notifyAll():不能重写。唤醒正在等待对象监视器的所有线程。

8、public final void wait(long timeout) throws InterruptedException:不能重写。导致当前线程等待,直到另一个线程调用此对象的notify()方法或notifyAll()方法,或指定的时间已过。当前的线程必须拥有该对象的显示器。

9、public final void wait(long timeout, int nanos) throws InterruptedException:多了nanos参数,这个参数表示额外时间(以毫微秒为单位,范围是 0-999999)。 所以超时的时间还需要加上nanos毫秒。

10、public final void wait() throws InterruptedException:导致当前线程等待,直到另一个线程调用该对象的notify()方法或notifyAll()方法。 换句话说,这个方法的行为就好像简单地执行呼叫wait(0) 。跟之前的2个wait方法一样,只不过该方法一直等待,没有超时时间这个概念。

二、Scanner类

一个简单的文本扫描器,可以使用正则表达式解析原始类型和字符串。可以调用方法来获取输入框的内容。

    主要的方法:

1、主要用于读取内容

java通用ResultVO java通用返回类_Test


java通用ResultVO java通用返回类_java通用ResultVO_02

nextxxx()方法表示只能读取xxx类型的数据。
next()方法:只读取输入直到空格。它不能读两个由空格或符号隔开的单词。此外,next()在读取输入后将光标放在同一行中。(next()只读空格之前的数据,并且光标指向本行)

nextLine()方法:读取输入,包括单词之间的空格和除回车以外的所有符号(即。它读到行尾)。读取输入后,nextLine()将光标定位在下一行。

import java.util.Scanner;

public class Test_Scanner {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        System.out.println("请输入字符串,不能够识别空格的");
        String a = scanner.next();
        System.out.println("a:"+a);
        /*
        结果:请输入字符串,不能够识别空格的
             hello world
             a:hello
         */


        System.out.println("请输入字符串,能够识别空格的");
        String b = scanner.nextLine();
        System.out.println("b:"+b);
        /*
        结果:请输入字符串,能够识别空格的
             hello world
             b:hello world
         */

        //nextxxx()类似
        System.out.println("请输入一个整数");
        System.out.println("c:"+scanner.nextInt());
        /*
        结果:请输入一个整数
             123
             c:123
         */

    }
}

2、主要用于判断内容的类型

java通用ResultVO java通用返回类_java通用ResultVO_03

import java.util.Scanner;

public class Test2_Scanner {
    public static void main(String args[]) {
        Scanner scan = new Scanner(System.in);	//构造Scanner类的对象scan,接收从控制台输入的信息
        System.out.println("请输入你的姓名");
        String name = scan.nextLine();//接收一个字符串,可以加除Enter以外的所有符号,包括空格和Tab
        System.out.println("请输入你的ID");
        String ID ;
        while(scan.hasNextLine()) {// hasNextLine()方法判断当前是否有输入,当键盘有输入后执行循环
            if(scan.hasNextInt()) {// 判断输入的值是否为整数类型,当为整数类型时执行循环
                ID = scan.nextLine();
                System.out.println("你输入的姓名为:"+name);
                System.out.println("你输入的ID为:"+ID);
                break;
            }else {
                System.out.println("ID需要输入数字!");
                ID = scan.nextLine();
                continue;
            }
        }
    }
}

三、String类

String类代表字符串,引用数据类型。
1、定义及初始化:
(1)String str1 = "hello world";该方法定义字符串,会将字符串存入字符串常量池中,再使用该种方法定义,若存在一样的字符串,则会引用常量池中的字符串。
(2)char[] Array = {'a','b','c'}; String str3=new String(Array);该方法,会建立新的对象存放到堆中,然后通过地址值引用。

public class Test_String {
    public static void main(String[] args) {
        String str1="abc";
        String str2="abc";

        char[] Array = {'a','b','c'};
        String str3=new String(Array);
        String str4=new String(Array);

        System.out.println("str1="+str1);
        System.out.println("str2="+str2);
        System.out.println("str3="+str3);
        System.out.println("str4="+str4);

        System.out.println("str1==str2: "+(str1==str2));
        System.out.println("str1==str3: "+(str1==str3));
        System.out.println("str1.equals(str3): "+(str1.equals(str3)));
        System.out.println("str3==str4: "+(str3==str4));
    }
}

结果:
str1=abc
str2=abc
str3=abc
str4=abc
str1 == str2: true
str1 == str3: false
str1.equals(str3): true
str3 == str4: false

java通用ResultVO java通用返回类_System_04


2、常用方法:

(1)public int length():获取字符串长度。

(2)public String concat(String str):将指定的字符串连接到该字符串的末尾。原来的字符串不会发生变化,产生一个新的字符串值。

(3)public char charAt(int index):获取指定索引位置的单个字符,返回值为char型。
(4)public int indexOf(String str):返回指定子字符串第一次出现的字符串内的索引。
          public int intindexOf(String str, int fromIndex) :返回指定子串的第一次出现的字符串中的索引,从指定的索引开始。

    两个方法的区别:

public class Test2_String {
    public static void main(String[] args) {
        String str1 = "hello world";
        System.out.println(str1.indexOf("l"));//2
        System.out.println(str1.indexOf("l",5));//9,从索引为5的地方开始数
    }
}

(5)public String substring(int index):返回一个字符串,该字符串是此字符串的子字符串。
          public String substring(int beginIndex, int endIndex) ;:返回一个字符序列,该序列是该序列的子序列。

public class Test2_String {
    public static void main(String[] args) {

        String str2="hello world";
        System.out.println(str2.substring(2));//llo world
        System.out.println(str2.substring(2,5));//llo

    }
}

(6)public char[ ] toCharArray();:将此字符串转换为新的字符数组。

public class Test2_String {
    public static void main(String[] args) {

        String str = "hello world";
        char[] chars = str.toCharArray();
        for(char s:chars){
            System.out.print(s+"-");
        }

//结果:h-e-l-l-o- -w-o-r-l-d-
    }
}

          public byte[ ]getBytes():使用平台的默认字符集将此 String编码为字节序列,将结果存储到新的字节数组中。

public class Test3_String {
    public static void main(String[] args) {

        String str = "hello world";
        byte[] bytes = str.getBytes();
        for(byte s:bytes){
            System.out.print(s+"-");
        }

//结果:104-101-108-108-111-32-119-111-114-108-100-
    }
}

          public String replace(char oldChar, char newChar):返回从替换所有出现的导致一个字符串 oldChar在此字符串 newChar 。

public class Test3_String {
    public static void main(String[] args) {

        String str = "hello world";
        System.out.println("str = "+str);
        String str_2=str.replace("l","*");
        System.out.println("str_2 = "+str_2);

//结果:str = hello world
//     str_2 = he**o wor*d
    }
}

其余方法详见JavaAPI文档。