常用API-1(Object类、String类、StringBuffer类、StringBuilder类)

1. Object类

Java语言的根类,即所有类的父类。

1.1 clone()

返回一个Object对象的复制。这个复制返回的是一个新对象。

clone() 是 Object 的 protected 方法,它不是 public,一个类不显式去重写clone(),其它类就不能直接去调用该类实例的 clone() 方法。

1.1.1 浅拷贝

拷贝对象和原始对象的引用类型引用同一个对象

使用步骤:

  1. 实现clone的类首先需要继承Cloneable接口(若未实现,就抛出异常:CloneNotSupportedException)。Cloneable接口实际上是一个标识接口,没有任何接口方法。
  2. 在类中重写Object类的clone()方法;
  3. 在clone()中调用super.clone()。无论clone类的继承结构是什么,super.clone()会直接或间接调用java.lang.Object类的clone()
  4. 把浅复制的引用指向原型对象新的克隆体。
class Obj implements Cloneable{
	private int aInt=0;
	public int getAInt() {
		return aInt;
	}
	public void setAInt(int int1) {
		aInt=int1;
	}
	public void changeInt() {
		this.aInt=1;
	}
	public Object clone() {
		Object o=null;
		try {
			o=(Object)super.clone();
		}catch(CloneNotSupportedException e) {
			e.printStackTrace();
		}
		return o;
	}
}

public class DBTest{
	public static void main(String[] args) {
		Obj a=new Obj();
		Obj b=(Obj)a.clone();
		b.changeInt();
		System.out.println("a:"+a.getAInt());
		System.out.println("b:"+b.getAInt());
		}
	
}

运行结果:

a:0
b:1

1.1.2 深复制

拷贝对象和原始对象的引用类型引用不同对象

在对对象调用clone()完成复制之后,接着对对象中的非基本类型的属性也调用clone()完成复制

import java.util.Date;

class Obj implements Cloneable{
	private Date birth=new Date();
	public Date getBirth() {
		return birth;
	}
	public void setBirth(Date birth) {
		this.birth=birth;
	}
	public void changeDate() {
		this.birth.setMonth(4);
	}
	public Object clone() {
		Obj o=null;
		try {
			o=(Obj)super.clone();
		}catch(CloneNotSupportedException e) {
			e.printStackTrace();
		}
		//实现深复制
		o.birth=(Date)this.getBirth().clone();
		return o;
	}
}

public class DBTest{
	public static void main(String[] args) {
		Obj a=new Obj();
		Obj b=(Obj)a.clone();
		b.changeDate();
		System.out.println("a:"+a.getBirth());
		System.out.println("b:"+b.getBirth());
	}
}

运行结果:

a:Tue Nov 27 15:40:48 CST 2018
b:Sun May 27 15:40:48 CST 2018

Date.setMonth(int):都标有删除线,因为被废弃了。是因为Date类在设计中有很多问题,如getYear指的是1900年以来的年数,getMonth是从0开始的。

setMonth(4)实际上是设置为5月,May

1.2 equals()

比较两个对象是否相同。

基本类型比较的是值,引用类型比较的是地址。

满足:自反性、对称性、传递性和一致性(多次调用结果一样)。

  1. x.equals(x); // true
  2. x.equals(y) == y.equals(x); // true
  3. if (x.equals(y) && y.equals(z)) x.equals(z); // true;
  4. x.equals(y) == x.equals(y); // true

与 null 的比较:对任何不是 null 的对象 x 调用 x.equals(null) 结果都为 false

要根据对象属性值进行比较时,需重写equals()

public boolean equals(Object obj) {
	if(this==obj)
		return true;
	if(!(obj instanceof Person))
		return false;
	//将obj向下转型为Person引用,访问其属性
	Person p=(Person) obj;
	return this.age==p.age;
}
  • 在重写Object中的equals()时,要注意equals(Object obj)的参数类型时Object;
  • 在调用对象属性的时候,要进行类型转换,但转换之前,必须进行类型判断。

1.2.1 equals()源码

public boolean equals(Object obj){
    return (this==obj);
}
  • 使用==
  • 比较两个对象的内存地址

1.2.2 equals() 与 ==

  • 对于基本类型,== 判断两个值是否相等,基本类型没有 equals() 方法
  • 对于引用类型,== 判断两个变量是否引用同一个对象,而 equals() 判断引用的对象是否等价。

1.3 toString()

返回该对象的字符串表示(对象类型+@+内存地址值)

Syso(s);——默认调用toString()

Syso(s.toString());和上面一句输出一样

需按对象的属性得到相应的字符串表示时,需要重写toString();

class Person extends Object{
	int age;
	public String toString() {
		return "Person [age="+age+"]";
	}
}

toString()源码

String toString(){
    return getClass().getName()+"@"+Integer.toHexString(hashCode());
}
  • getClass():返回一个对象。返回Object的运行时类(字节码对象)
  • getName():返回字节码名字(类名)
  • @:分隔符
  • Integer.toHexString():类名调用方法,说明toHexString()是static方法。它以十六进制无符号整数形式返回一个整数参数的字符串表现形式
  • hashCode():无对象调用,则属于Object,返回对象的哈希码值。阿静对象的内存地址以整数形式返回。

1.4 hashCode()

hasCode() 返回散列值,而 equals() 是用来判断两个对象是否等价。

等价的两个对象散列值一定相同,但是散列值相同的两个对象不一定等价。

在覆盖 equals() 方法时应当总是覆盖 hashCode() 方法,保证等价的两个对象散列值也相等。

下面的代码中,新建了两个等价的对象,并将它们添加到 HashSet 中。

我们希望将这两个对象当成一样的,只在集合中添加一个对象,但是因为 EqualExample 没有实现 hasCode() 方法,因此这两个对象的散列值是不同的,最终导致集合添加了两个等价的对象。

EqualExample e1 = new EqualExample(1, 1, 1);
EqualExample e2 = new EqualExample(1, 1, 1);
System.out.println(e1.equals(e2)); // true
HashSet<EqualExample> set = new HashSet<>();
set.add(e1);
set.add(e2);
System.out.println(set.size()); // 2

理想的散列函数应当具有均匀性,即不相等的对象应当均匀分布到所有可能的散列值上。

2. String类

字符串是常量,它们的值在创建之后不能更改

字符串本身不能更改,但str变量中记录的地址值可以改

String str="CSDN";

str="Zxin";

2.1 赋值方式

2.1.1 使用双引号的方式创建的对象和使用new方式(构造函数)创建的对象的区别

String s1=new String("hello");

String s2="hello"

String s3="hello";

s1==s3;//false

s2==s3;//true

字符串内容存储在方法区的常量池里面,便于字符串的重复使用。

public class Code2 {
	public static void main(String[] args) {
		String s1=new String("hello");
		String s2="hello";
		String s3="hello";
		String s4=new String("hello");
		System.out.println(s1==s3);//false
		System.out.println(s2==s3);//true
		System.out.println(s1==s4);//false		
	}
}

2.2 构造方法

String();
String(byte[] bytes);
String(byte[] bytes,int offset, int length);
String(char[] value);
String(char[] value,int offset,int length);
String(String original)——把字符串数据封装成字符串对象

2.3 方法

length():字符个数
subString(int beginIndex):从指定位置到字符串末尾的所有字符
subString(int beginIndex,int endIndex):从指定位置开始到指定位置结束的所有字符串[beginIndex,endIndex)

trim():去掉字符串两端空格

split(String str):按照指定符号分割字符串

2.3.1 查找

startWith(String prefix):以给定字符串开始
endsWith(String suffix):以给定字符串结尾
contains(CharSequence s):判断是否包含给定字符串

  • 是,返回第一次出现该字符串的索引
  • 否,返回-1

indexOf(String str):判断是否包含给定字符串

  • 是,返回true
  • 否,false

charAt(int index):获取字符串第index位置的字符

  • index范围:[0,length()-1]

2.3.2 转换

getBytes():将字符串转换成一个字节数组

to CharArray():将字符串转换为一个字符数组

to LowerCase():转换为小写字符串

to UpperCase():转换为大写字符串

2.3.3 判等

equals(Object obj):比为骄傲字符串的内容是否相同

equalsIgnoreCase(String str):忽略大小写

直接打印引用类型变量时,默认调用该类型进行重写后的toString()。

2.4 字符串拼接

String s="hello";

s+="world";

字符串拼接很耗时,也很浪费空间。

  • String的值是不可变的,这就导致每次对String的操作都会生成新的字符串内容

3. StringBuffer

又称不可变字符序列

类似于String的字符缓冲区,通过某些方法调用可以改变该序列的长度和内容。

它是一个容器,可以装很多字符串,并且能够对其中的字符串进行各种操作。

3.1 方法

append(String str):添加字符串

insert(int offset,String str):在指定位置插入

delete(int start,int end):删除子序列

replace(int start,int end,String str):替换指定范围的内容(end-start=str.length()??)

reverse():反转

toString()

以上方法返回的都是当前对象自己——StringBuffer可以改变当前字符序列的长度和内容

3.2 对象的方法链式调用(运行下)

不断添加数据,要对缓冲区的最后数据进行操作,必须转换成为字符串才可以。

String str=sb.append(true).append("hello").toString();

无论多少数据,数据什么类型都不重要,只要最终编程字符互传就可以使用StringBuffer这个容器。

4. StringBuilder

用在字符串缓冲区被单个线程使用时。

若可以,优先采用此类,它比StringBuffer快。

属于java.lang包,不用导包。

String内容是固定的;StringBuilder内容是可变的。

4.1 成员方法

capcacity():返回当前容量——理论值

length():返回长度(字符个数)——实际值

append(任意类型):添加数据,并返回自身对象

reverse()

4.2

StringBuilder sb=bew StringBuilder();
StringBuilder sb2=sb.append("hello");

运行之后,sb和sb2里都是hello。

4.3 String<------>StringBuilder

1、String--->StringBuilder:StringBuilder(String s);构造方法

2、StringBuilder--->String:toString();

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值