java-Object类和String类的常用方法

一、简介Object类

    1、Object类是所有类的父类,即每个类都直接或简介继承自该类。所以一个Object类型的变量可以引用任何对象,不论是类实例还是数组。

    在不明确给出父类的情况下,Java会自动把Object作为要定义类的父类。

    Object类有一个默认构造方法public Object(),在构造子类实例时,都会先调用这个默认构造方法。

 二、方法预览

    1、Object()

     默认构造方法

    2、clone()

     创建并返回此对象的一个副本(复制对象)

    3、equals(Object obj)

     指示某个其他对象是否与此对象"相等"。

    4、finalize()

     当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法,该方法用于释放资源。

    5、getClass()

     返回一个对象的运行时类,获得类型的信息。

    6、hashcode()

     该方法将对象的内存地址进行哈希运算,返回一个int类型的哈希值(返回该对象的哈希码值)。

     功能:是相等对象拥有相同的哈希码,尽量让不等的对象具有不同的哈希码。

    7、notify()

     唤醒在此对象监视器上等待的单个线程。

    8、notifyAll()

     唤醒在次对象监视器上等待的所有线程。

    9、toString()

     返回该对象的字符串表示。以便用户能够获得一些有关对象状态的基本信息。简单说就是利用字符串来表示对象。

    10、wait()

     导致当前的线程等待,直到其他线程调用此对象的notify()方法或notifyAll()方法。

    11、wait(long timeout)

     导致当前的线程等待,直到其他线程调用此对象的notify()方法或notifyAll()方法,或者超过指定的时间量。

    12、wait(long timeout, int nanos)

     导致当前的线程等待,直到其他线程调用此对象的notify()方法或notifyAll方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量。

 三、

   1、为什么要重写equals()方法?

    因为Object类中定义的equals()方法是用来比较两个引用所指向的对象的内存地址是否一致。

    源码:

    public boolean equals(Object obj) {

        return (this == obj);

    }

     ("=="两边是基本类型比较的是内容,"=="两边是引用类型(class)比较的是否对同一对象的引用,即比较两个引用所指向的对象的内存地址是否一致。)

    而我们经常会希望两个不同对象的某些属性值相同时,就认为它们相同。所以我们要重新equals()方法。

   2、为什么要重写hashCode()方法?

   需要注意的是:

    a、在java应用程序运行时,无论何时多次调用同一个对象时的hashCode()方法,这个对象的hashCode()方法的返回值必须是相同的一个int值

    b、如果两个对象equals()返回值为true,则它们的hashCode()也必须返回相同的int值

    c、如果两个对象equals()返回值为false,则它们的hashCode()返回值也必须不同

    由于hashCode方法定义在Object类中,因此每个对象都有一个默认的散列码,其值为对象的存储地址。如果重新定义equals方法,就必须重新定义hashCode方法,以便用户可以将对象插入到散列表中。(要保证上面所述b,c原则)

二、Java - String 类常用方法

JackWu  JavaGolang  3月18日

字符串操作是计算机程序设计中最常见的行为,本文继续介绍 String 类常用方法。

重载 "+" 与 StringBuilder

我们都知道 String 对象是不可变的,可以给一个 String 对象加任意多个别名,因为它具有只读特性,所以指向它的任何一个引用都不会改变它的值,因此任意多个引用也不会有什么相互影响。

但是这样的不可变性会带来一定的效率问题,比如 String 对象重载的 "+" 操作符,操作符重载的含义:一个操作符应用于特定的类时,被设计者赋予了特殊含义(在 Java 中 String 类仅有 “+” 和 “+=” 两个重载操作符)。

测试代码:

publicclassTestString{

publicstaticvoidmain(String[] args){

String str ="a"+"b"+10;

System.out.println(str);

}

}

反编译结果:

Code:

0: ldc#2// String a

2: astore_1

3: new#3// class java/lang/StringBuilder

6: dup

7: invokespecial#4// Method java/lang/StringBuilder."<init>":()V

10: aload_1

11: invokevirtual#5// Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

14: ldc#6// String b10

16: invokevirtual#5// Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

19: invokevirtual#7// Method java/lang/StringBuilder.toString:()Ljava/lang/String;

22: astore_1

23: getstatic#8// Field java/lang/System.out:Ljava/io/PrintStream;

26: aload_1

27: invokevirtual#9// Method java/io/PrintStream.println:(Ljava/lang/String;)V

30: return

我们可以惊奇的发现:代码中使用的是 “+” 重载符,没有使用到 StringBuilder 类,但是编译器为了优化它自作主张的使用了 StringBuilder 类,因为 StringBuilder 类更高效,大家会不会觉得反正编译器可以帮我们用 StringBuilder 优化,那是不是意味着我们可以随意使用 “+” 重载操作符呢?再来看下面这个例子:

测试代码:

publicstaticvoidmain(String[] args){

String result ="";

for(inti =0; i <100; i ++) {

result += i;

}

System.out.println(result);

}

反编译:

Code:

0: ldc#2// String

2: astore_1

3: iconst_0

4: istore_2

5: iload_2

6: bipush100

8: if_icmpge36

11: new#3// class java/lang/StringBuilder

14: dup

15: invokespecial#4// Method java/lang/StringBuilder."<init>":()V

18: aload_1

19: invokevirtual#5// Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;

22: iload_2

23: invokevirtual#6// Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;

26: invokevirtual#7// Method java/lang/StringBuilder.toString:()Ljava/lang/String;

29: astore_1

30: iinc2,1

33:goto5

36: getstatic#8// Field java/lang/System.out:Ljava/io/PrintStream;

39: aload_1

40: invokevirtual#9// Method java/io/PrintStream.println:(Ljava/lang/String;)V

主要是关注编号为第 5 到第 33 : 这里明显看出 “+=” 操作符编译器还是使用  StringBuilder 类进行优化,但是需要强烈注意的是:StringBuilder 的初始化是在循环体内创建的,即每循环一次,就会创建新的 StringBuilder 对象,这样会造成大量的对象垃圾导致 GC 操作频繁。

**优化**:要进行大量字符串拼接操作,最好的方式是定义一个 StringBuilder 或 StringBuffer 对象进行字符串连接,少量的字符串拼接可以使用重载操作符 “+” 或 “+=”。

优化代码:

StringBuilder sb =newStringBuilder();

for(inti =0; i <100; i ++) {

sb.append(i);

}

System.out.println(sb);

极容易忽略的:无意识递归

来看一个简单的代码:

publicclassTestStringStackOverflow{

// 定义一个 Person 类

staticclassPerson{

privateString name;

publicPerson(String name){

this.name = name;

}

/**

* 重写 toString() 方法,注意最后的 this 关键字

*/

@Override

publicStringtoString()

{

return"Person{"+"name='"+ name +'\''+'}'+this;

}

}

publicstaticvoidmain(String[] args){

Person person =newPerson("jackwu");

System.out.println(person);

}

}

不知道各位有没有发现存在什么问题?这里一不小心写了无限循环的递归调用,会导致`java.lang.StackOverflowError`异常,所以千万不要在 toString() 方法输出 this。

Exceptioninthread"main"java.lang.StackOverflowError

at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:449)

at java.lang.StringBuilder.append(StringBuilder.java:136)

at com.java.blog.base.TestStringStackOverflow$Person.toString(TestStringStackOverflow.java:19)

解决方案: 使用super.toString() 方法打印内存地址.这里的 super 父类是Object类。

String 操作方法

String 操作方法当需要改变字符串的内容时,String类的方法都会返回一个新的String对象。如果内容没有发生改变,String 的方法只是返回指向原对象的引用而已,这节省了存储空间以及避免了额外的花销。

方法参数,重载版本应用

构造器String() 

String(String original) 

String(char value[]) 

String(char value[], int offset, int count) 

String(byte bytes[])

String(StringBuffer buffer) 

String(StringBuilder builder)

创建String对象

length()int length()String中字符的个数

charAt()charAt(int index)取得String中该索引位置上的char

getChars(),getBytes()getChars(char dst[], int dstBegin) 

getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) 

getBytes(int srcBegin, int srcEnd, byte dst[], int dstBegin) 

getBytes(String charsetName) 

getBytes(Charset charset) 

getBytes()

复制char或byte到一个目标数组中

toCharArray()char[] toCharArray()生成一个char[],包含String的所有字符

equals(),equalsIgnoreCase()boolean equals(Object anObject) 

qualsIgnoreCase(String anotherString)

比较两个String的内容是否相同

compareTocompareTo(String anotherString)按词典顺序比较String的内容,比较结果为负数,零或正数.注意,大小写并不等价

containsboolean contains(CharSequence s)当且仅当此字符串包含指定的时,才返回true

contentEquals()boolean contentEquals(StringBuffer sb) 

boolean contentEquals(CharSequence cs)

如果该String与参数的内容完全一致,则返回true

equalsIgnoreCaseboolean equalsIgnoreCase(String anotherString)与之进行比较的String  忽略大小写,如果两个String的内容相同,则返回true

regionMatches()regionMatches(int toffset, String other, int ooffset,int len)返回boolean结果,以表明所比较区域是否相等

startsWith()boolean startsWith(String prefix, int toffset) 

boolean startsWith(String prefix)

返回boolean结果,以表明String是否以此参数起始

endsWith()boolean endsWith(String suffix)返回boolean结果,以表明此参数在String中的起始索引.lastIndexOf()是从后向前搜索

indexOf(),lastIndexOf()int indexOf(int ch)

indexOf(int ch, int fromIndex) 

int lastIndexOf(int ch)

lastIndexOf(int ch, int fromIndex)

如果该String并不包含此参数,就返回-1;否则返回此参数在String中起始的索引.lastIndexOf()是从后向前搜索

substring(subSequence())String substring(int beginIndex)

String substring(int beginIndex, int endIndex)

CharSequence subSequence(int beginIndex, int endIndex)

返回一个新的String,以包含参数指定的子字符串

concat()String concat(String str)返回一个新的String对象,内容为起始Stirng连接上参数String

replace()String replace(char oldChar, char newChar)返回替换字符后的新String对象.如果没有替换发生,则返回原始的String对象

toLowerCase,toUpperCase()String toLowerCase(Locale locale) 

String toLowerCase()

String toUpperCase(Locale locale)

String toUpperCase()

将字符的大小写改变后,返回一个新String对象.如果没有发生改变,则返回原始的String对象

trim()String trim()将String两端的空白字符删除后,返回一个新的String对象.如果没有改变发生,则返回原始的String对象

valueOf()重载版本:Object;char[];char[],偏移量,字符个数; boolean; char; int; long; float; double返回一个表示参数内容的String

intern()native String intern()为每个唯一的字符序列生成一个且仅生成一个String引用

格式化输出

System.out.format()

用于PrintStream或PrintWriter对象,其中包括System.out对象。

System.out.format("%-15s %5s %10s\n","item","qty","price");

System.out.format("%-15s %5s %10s\n","----","---","-----");

System.out.format("%-15.15s %5d %10.2f\n","lalala",4,4.25);

输出

item              qty      price

----              ---      -----

lalala44.25

Formatter类

Formatter 类可以将格式化字符串与数据翻译成需要的结果,Formatter类格式化抽象语法: %[argument_index][flags][width][.precision]conversion

 用"-"标志来改变对齐方向(默认右对齐),添加了"-"表示左对齐 ;

width: 控制一个域的最小尺寸;

precision: 用来指明最大尺寸,用于String时,它表示打印String时输出字符的最大数量.用于浮点数时,表示小数显示的位数(默认6位),小数过多则舍入,过少则在尾部补零,用于整数时,会出发异常。

Formatter 转换

类型转换字符说明

d整数型(十进制)

cUnicode字符

bBoolean值

sString

f浮点数(十进制)

e浮点数(科学计数法)

x整数(十六进制)

h散列码(十六进制)

%字符'%'

String.format()

是一个 static 方法,接受与 Formatter.format() 方法一样的参数,但返回一个 String 对象。

String.format() 内部,它创建一个Formatter对象,然后将你传入的参数转给 Formatter 。

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

推荐阅读更多精彩内容