- 2、==和equals的区别
2.1、==:对于基本类型比较的是值是否相同,对于引用类型比较的是引用(地址)是否相同
2.2、equals:查看equals方法的具体实现(Object.java),可知equals本质上就是==
public boolean equals(Object obj) {
return (this == obj);
}
当使用equals比较两个有相同值的对象时,结果返回false;而当比较两个有相同值的String对象时,结果却返回true,这是为什么?
代码示例1:比较两个有相同值的对象
public class Cat {
private String name;
public Cat(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
Cat c1 = new Cat("肥波");
Cat c2 = new Cat("肥波");
System.out.println(c1.equals(c2));//结果为false
}
}
代码实例2:比较两个相同值的String对象
String s1 = new String("张三");
String s2 = new String("张三");
System.out.println(s1.equals(s2));//true
我们查看String对象比较使用的equals方法的具体实现,发现编译器把我们带到了String.java
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}
原来是 String 重写了 Object 的 equals 方法,把引用比较改成了值比较
2.3、两者对比
代码示例:
public static void test(){
String x = "string";
String y = "string";
String z = new String("string");
System.out.println(x==y);//true
System.out.println(x==z);//false
System.out.println(x.equals(y));//true
System.out.println(x.equals(z));//true
}
代码解读:
因为x和y指向的是同一个引用,所以==也是true,而new String()方法则重写开辟了内存空间,所以==结果为false,而equals比较的一直是值,所以结果都为true
2.4、总结
==对于基本类型来说是值比较,对于引用类型比较的是引用;而equals默认情况下是引用比较,只是很多类重写了equals方法,如String、Integer把equals方法变成了值比较,所以一般情况下equals比较的是值是否相等
- 3、两个对象的hashCode()相同,则equals()也一定为true,对吗?
代码实例
String str1 = "通话";
String str2 = "重地";
System.out.println(String.format("str1: %d | str2: %d",str1.hashCode(),str2.hashCode()));
System.out.println(str1.equals(str2));
执行结果:
str1:1179395 | str2:1179395
false
原因:在散列表中,hashcode()相等即两个键值对的哈希值相等,而哈希值相等键值对不一定相等
拓展:
散列表(Hash table,也叫哈希表),是根据关键码值(Key value)而直接进行访问的数据结构。也就是说,它通过把关键码值映射到表中一个位置来访问记录,以加快查找的速度。这个映射函数叫做散列函数,存放记录的数组叫做散列表。
给定表M,存在函数f(key),对任意给定的关键字值key,代入函数后若能得到包含该关键字的记录在表中的地址,则称表M为哈希(Hash)表,函数f(key)为哈希(Hash) 函数。
-
4、final在java中的作用
final修饰的类叫最终类,该类不能被继承
final修饰的方法不能被重写
final修饰的变量叫常量,常量必须初始化,初始化后值不能被修改 -
5、Math.round(-1.5)等于多少
等于-1,在数轴上取值时,中间值(0.5)向右取整,所以正0.5是往上取整,负0.5是直接舍弃 -
6、String属于基础的数据类型吗
不属于基础数据类型,属于对象,基础数据类型有:byte、boolean、char、short、int、float、long、double、 -
7、java中操作字符串的类及其区别
String:声明的是不可变对象,每次操作都会产生新的String对象,然后将指针指向新的String对象。
StringBuffer和StringBuilder:可以在原有对象的基础上操作,所以经常改变字符串内容的情况下最好还是不要使用String。 -
8、String str = "i"与String str = new String(“i”)一样吗?
内存的分配方式不一样。对于前者,Java虚拟机会将其分配到常量池中;而后者则会分配到堆内存中。 -
9、如何将字符串反转?
使用StringBuilder或者stringBuffer的reverse()方法
//StringBuffer
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("abcdefg");
System.out.println(stringBuffer.reverse());//gfedcba
//StringBuilder
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("abcdefg");
System.out.println(stringBuilder.reverse());//gfedcba
-
10、String类的常用方法
(1)indexOf():返回指定字符的索引
(2)charAt();返回执行索引处的字符
(3)replace():字符串替换
(4)trim():去除字符串两端空白
(5)split():分割字符串,返回一个分割后的字符串数组
(6)getBytes():返回字符串的byte类型数组
(7)length():返回字符串长度
(8)toLowerCase():将字符串转成小写字母
(9)toUpperCase():将字符串转成大写字母
(10)substring():截取字符串
(11)equals():字符串比较 -
11、抽象类必须要有抽象方法吗
不需要,如下抽象类没有抽象方法也可正常运行
abstract class Cat {
public static void sayHi() {
System.out.println("hi~");
}
}
-
12、普通类和抽象类的区别
普通类:不能包含抽象方法;不能直接实例化。
抽象类:可以包含抽象方法,可以直接实例化。 -
13、抽象类能使用final修饰吗
不可,定义抽象类就是让其他类继承,如果定义为final该类就不能被继承,彼此矛盾,编译器会提示错误 -
14、接口和抽象类的区别
(1)实现:抽象类的子类使用extends来继承;接口必须使用implement来实现接口。
(2)构造函数:抽象类可以有构造函数;接口不可以有。
(3)main方法:抽象类可以有能够运行的main方法;接口不能有。
(4)实现数量:类只能继承一个抽象类;但可以实现很多个接口。
(5)访问修饰符:抽象类中的方法是任意访问修饰符,接口总的方法默认使用public修饰。 -
15、IO流的分类
(1)按功能:输入流(input)和输出流(output)。
(2)按类型:字节流和字符流。字节流按8位传输以字节为单位输入输出数据;字符流按16位传输以字符为单位输入输出数据。 -
16、BIO、NIO、AIO的区别
BIO:Block IO同步阻塞式IO,即我们平常用的传统IO,模式简单使用方便,并发处理能力低。
NIO:New IO同步非阻塞式IO,传统IO的升级,客户端和服务器通过Channel(通道)通讯,实现了多路复用。
AIO:Asynchronous IO是NIO的升级,也教NIO2,实现了异步非堵塞IO,异步IO的操作基于事件和回调机制。 -
17、Files的常用方法
(1)Files.exists():检测文件是否存在。
(2)Files.createFile():创建文件。
(3)Files.createDirectory():删除一个文件或目录。
(4)Files.delete():复制文件。
(5)Files.copy():复制文件。
(6)Files.move():移动文件。
(7)Files.size():查看文件个数、
(8)Files.read():读取文件。
(9)Files.write():写入文件。