Java——面试题
本人是个新手,写下博客用于自我复习、自我总结。
如有错误之处,请各位大佬指出。
参考教材:零基础学Java
一、Java可以用非0来代表true吗?
Java是一种强类型的语言,它对条件表达式有非常严格的规定,只能使用boolean型的数据进行条件判断。如果使用整型的非0数进行条件判断,则体现为语法错误。
例如:if(100){····} 是错误的。
也就是说在if、for这样的语句里,只能使用false和true两种值。
例如:if(100>90){····}
其实,这在一定程度上也是为了保证程序的安全,让开发者明确应该如何来判断条件。如果使用非0的条件,有可能运行时的值并不是开发者需要的,比如变量还未初始化。另外Java对于boolean型的变量,也需要在使用前进行初始化操作。
例如:
boolean a
if(a){····} 是错误的。
二、StringBuffer和StringBuilder存在的作用是什么?
如果通过String来直接相加拼接字符串的效率是很低的,其中可能会产生很多多余的String对象,而且如果需要拼接的字符串数量成千上万的话,那么JVM的负荷是非常大的,严重地影响到程序的性能。也就是说,在遇到需要拼接大量字符串的话,StringBuffer和StringBuilder类的作用就体现出来了,它们是对String的一种补充。这样可以提高程序性能:
public class StringBBTest{
public static void main(String args[]){
String a="a";
String b="b";
String c="c";
StringBuffer sb=new StringBuffer();
sb.append(a);
sb.append(b);
sb.append(c);
String abc=sb.toString();
System.out.println(abc);
}
}
三、二维数组的长度是否固定?
Java的二维数组其实是:先创建一个一维数组,然后该数组的元素在引用另外一个一维数组。在使用二维数组的时候,通过两个中括号“[]”来访问每一层维度的引用,直到访问到最终的数据。
例:
public class Array{
public static void main(String args[]){
int [][] arr=new int[3][];
arr[0]=new int[]{4};
arr[1]=new int[]{4,5};
arr[2]=new int[]{4,5,6};
for(int[] a:arr){
for(int i:a){
System.out.print(i+"\t");
}
System.out.println();
}
}
}
实例化二维数组时,并没有指定第二维的长度,也没有必要指定,因为它们的长度是可以各异的。上例的arr.length等于3,但是arr[i].length却不相同。因此,遍历该二维数组时,打印出来的长度也是不同的。
四、符合什么条件的数据集合可以使用foreach循环?
foreach循环就是遍历一个集合里的原上诉,起到替代迭代器的作用。从语法上来讲,数组或者实现了Iterable接口的类实例,都是可以使用foreach循环的。
例:
List list=new ArrayList();
list.add("a");
list.add("b");
list.add("c");
for(String s:list){
System.out.println(s);
}
String[] arr={"a","c","b"};
for(String s:arr){
System.out.println(s);
}
数组是Java规定的东西,只能遵照它的使用语法来使用。但是开发人员可以自定义一个集合类。该自定义集合类需要做以下一些事情:
1)定义一个类,包含一个整型下标成员变量和一个集合对象(如数组或链表)
2)该类实现Iterable接口
3)提供一个Iterable接口的实现,或者它本身就实现Iterator接口
4)使用下标成员变量和集合对象来完成Iterator接口所需要的方法
例:
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class MyForeach{
public static void main(String args[]){
MyList list=new MyList();
list.getList().add("a");
list.getList().add("b");
list.getList().add("c");
for(String s:list){
System.out.println(s);
}
}
}
class MyList implements Iterator<String>,Iterator<String>{//自定义链表类
private int loc=0; //当前的下标
private List<String> list=new ArrayList<String>();//存储数据
public boolean hasNext(){ //是否有下个元素
return list.size()>loc;
}
public String next(){ //得到下一个元素
return list.get(loc++);
}
public void remove(){ //删除当前下标的元素
list.remove(loc);
}
public List<String> getList(){
return list;
}
public void setList(List<String> list){
this.list=list;
}
public Iterator<String> iterator(){ //得到迭代器
return this;
}
}
五、接口与抽象类的区别?
抽象类是一种功能不全的类,接口只是一个抽象方法声明和静态不能被修改的数据的集合,两者都不能被实例化。从某种意义上说,接口是一种特殊形式的抽象类,在Java语言中,抽象类表示一种继承关系,一个类只能继承一个抽象类,而一个类却可以实现多个接口。