美文网首页
Object类和String类的常用方法

Object类和String类的常用方法

作者: LaobingFung | 来源:发表于2019-02-19 14:59 被阅读0次

Java中所有类都直接或间接继承Object类,而String类是Java中最常用的类之一,总结一下这两个类的一些常用方法。

Object类的常用方法

  • clone()
    clone方法可以实现Java对象的复制,然而如果被复制的对象中有引用类型的成员,该方法只是将对应成员变量设置为同样的引用对象,原对象和复制出来的对象的该成员变量是同一个引用变量,修改其中之一会影响另外一个对象,这种复制被称为浅复制
    一个类要调用Object的clone方法,需要实现Cloneable接口。
package model;

public class Student implements Cloneable {
    public String name;
    public int age;
    public Teacher teacher;

    public Student(String name, int age, Teacher teacher) {
        this.name = name;
        this.age = age;
        this.teacher = teacher;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

package model;

public class Teacher {
    public String name;
    public int age;

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

import model.Student;
import model.Teacher;

public class Main {
    public static void main(String[] args) {
        Teacher zhang = new Teacher("Zhang", 40);
        Student liu = new Student("Liu", 20, zhang);
        System.out.println("复制前" + liu.teacher.name);
        try {
            Student wang = (Student) liu.clone();
            wang.teacher.name = "Li";
            System.out.println("复制后" + liu.teacher.name);
            System.out.println("复制后" + wang.teacher.name);
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}

输出结果如下,用clone方法将liu复制给wang,修改wang的teacher属性,liu的teacher也跟着变化了。

复制前Zhang
复制后Li
复制后Li

要实现深复制,需要修改Student类中引用类型成员,让其也实现clone方法,同时在Student的clone方法中调用。
将Student和Teacher类修改为

package model;

public class Student implements Cloneable {
    public String name;
    public int age;
    public Teacher teacher;

    public Student(String name, int age, Teacher teacher) {
        this.name = name;
        this.age = age;
        this.teacher = teacher;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        Student stu = (Student) super.clone();
        stu.teacher = (Teacher) teacher.clone();
        return stu;
    }
}

package model;

public class Teacher implements Cloneable {
    public String name;
    public int age;

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

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

输出结果

复制前Zhang
复制后Zhang
复制后Li
  • hashCode()
    hashCode()是Object的方法,可以获取对象的散列码,散列码是根据对象的内容计算出来的一个int型整数,散列码用于一些数据结构的存储中,可以优化数据存储结构,一般用在hashmap,hashset中,确定数据的存储位置。
    要注意的有三点:
    1. 两个相等的对象的hashCode()必须是相等的。
    2. 如果两个对象的hashCode()相等,这两个对象不一定相等(发生了哈希碰撞)。
    3. hashCode()的返回值并不能说是对象的存储位置,因为在发生了哈希碰撞的情况下会作进一步处理。
  • equals()
    equals()是Object的方法,用于判断this对象与传入参数是否相等,返回boolean类型值true或false。源码如下,可以看出来默认的equals()是用==判断两个对象是否相等,即判断是否是同一个引用对象,想要用equals()判断两个对象的值是否相等,需要重写该方法。
public boolean equals(Object obj){
        return (this==obj);
}

Java一些内置的引用类型都重写了equals方法,而当我们给自定义的数据类型重写equals方法时,需要注意以下几点:
1. 自反性(reflexive),对于任意不为 null 的引用值 x,x.equals(x) 一定是 true。
2. 对称性(symmetric),对于任意不为 null 的引用值 x 和 y ,当且仅当x.equals(y)是 true 时,y.equals(x)也是true。
3. 传递性(transitive),对于任意不为 null 的引用值x、y和z,如果 x.equals(y) 是 true,同时 y.equals(z) 是 true,那么x.equals(z)一定是 true。
4. 一致性 (consistent),对于任意不为null的引用值x和y,如果用于equals比较的对象信息没有被修改的话,多次调用时 x.equals(y) 要么一致地返回 true 要么一致地返回 false。
5. 对于任意非null的对象x,x.equals(null)返回false。

  • getClass()
    getClass()同样是Object的方法,调用对象的getClass方法可以返回该对象的类型类。类型类是指代表一个类型的类,是Class类的实例。
    同样可以获取类型类的方法还有:
    • 调用类的静态成员class
    • 调用Class类的静态方法forName(String className)
public class Main {
    public static void main(String[] args) {
        System.out.println(zhang.name.getClass());
        System.out.println(String.class);
        try {
            System.out.println(Class.forName("java.lang.String"));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

输出

class java.lang.String
class java.lang.String
class java.lang.String
  • toString()
    同样是Object的常用方法之一,默认返回字符串"类名@哈希码",源码如下:
    public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

当自定义类需要特定的toString返回值,需要重写该方法。


String类的常用方法

  • compareTo()
    该方法用来对比两个String类型,源码如下,从源码可以看出该方法进行了以下操作:
    取出两个字符串中较小的长度,在该长度内,比较两个字符串相同位置上的字符,如果出现不同字符,则返回字符的unicode编码差值,如果该长度范围内字符都相同,则返回两个字符差长度之差。
    public int compareTo(String anotherString) {
        int len1 = value.length;
        int len2 = anotherString.value.length;
        int lim = Math.min(len1, len2);
        char v1[] = value;
        char v2[] = anotherString.value;

        int k = 0;
        while (k < lim) {
            char c1 = v1[k];
            char c2 = v2[k];
            if (c1 != c2) {
                return c1 - c2;
            }
            k++;
        }
        return len1 - len2;
    }

运行一下代码

public class Main {
    public static void main(String[] args) {
        String str1 = "hello";
        System.out.println(str1.compareTo("hi"));
        System.out.println(str1.compareTo("hello"));
        System.out.println(str1.compareTo("hello1"));
    }
}

结果如下

-4
0
-1
  • concat()
    concat方法用于连接两个字符串,返回连接后的字符串,源码如下:
    public String concat(String str) {
        int otherLen = str.length();
        if (otherLen == 0) {
            return this;
        }
        int len = value.length;
        char buf[] = Arrays.copyOf(value, len + otherLen);
        str.getChars(buf, len);
        return new String(buf, true);
    }
  • equals()
    equals方法用于判断两个字符串是否相等,类似的方法有contentEquals(),两者的区别是前者会判断传入参数是否是String类型,而后者只比较两者的内容时候相同。
  • join()
    用特定字符连接字符串数组,返回字符串,传入参数可以是(String, String[])或多个字符串的形式,传入多个字符串时,将第一个字符串插入都后面的字符串之间形成新的字符串。
  • split()
    按照特定字符分割字符串,返回数组。
    该方法可以传入一个参数或两个参数,传入一个参数时实际调用split(String regex, 0),第二个参数为int类型,指分割后返回数组的元素个数。
  • trim()
    去除字符串首尾的空格。
  • isEmpty()
    判断是否是空字符串。
import java.util.ArrayList;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        String str1 = "Hello world!";
        String str2 = str1.concat(" This is java.");
        System.out.println(str2);
        StringBuffer str3 = new StringBuffer("Hello world!");
        System.out.println(str1.equals(str3));
        System.out.println(str1.contentEquals(str3));
        String.join("-", new String[]{"java", "is", "cool"});
        System.out.println(String.join("-", new String[]{"java", "is", "cool"}));
        List<String> list = new ArrayList<>();
        list.add("java");
        list.add("is");
        list.add("cool");
        String str4 = String.join(" ", list);
        System.out.println(str4);
        String[] strArr = str4.split(" ", 2);
        for (String str : strArr) {
            System.out.println(str);
        }
        String str5 = "     java is cool    ";
        System.out.println(str5);
        System.out.println(str5.trim());
        System.out.println(str5.isEmpty());
        String str6 = "";
        System.out.println(str6.isEmpty());
    }
}

输出如下:

Hello world! This is java.
false
true
java-is-cool
java is cool
java
is cool
     java is cool    
java is cool
false
true

相关文章

网友评论

      本文标题:Object类和String类的常用方法

      本文链接:https://www.haomeiwen.com/subject/ajyzeqtx.html