Object类和String类的常用方法

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容