@liayun
2016-05-31T17:40:18.000000Z
字数 9213
阅读 1459
java基础
面试题,对于以下代码:
String s1 = "abc"; // s1是一个类类型变量,"abc"是一个对象
String s2 = new String("abc");
s1和s2有什么区别?
解:s1在内存中有一个对象,s2在内存中有两个对象。
对于以上代码,下面的代码会输出什么呢?
System.out.println(s1==s2);
System.out.println(s1.equals(s2));
会发现第一句输出false
,第二句输出true
,得出结论:String类复写了Object类中的equals(),该方法用于判断字符串是否相同。
String类是用于描述字符串事物的,那么它就提供了多个方法对字符串进行操作。常见的操作有哪些?
获取
int length();----获取长度
char charAt(int index);
int indexOf(int ch);
返回的是ch在字符串中第一次出现的位置int indexOf(int ch, int fromIndex);
从fromIndex指定位置开始,获取ch在字符串中出现的位置int indexOf(String str);
返回的是str在字符串中第一次出现的位置int indexOf(String str, int fromIndex);
从fromIndex指定位置开始,获取str在字符串中出现的位置int lastIndexOf(int ch);
反向索引一个字符出现的位置例,
public static void sop(Object obj) {
System.out.println(obj);
}
public static void method_get() {
String str = "abcdeakpf";
// 长度
sop(str.length());
// 根据索引获取字符
sop(str.charAt(4)); // 当访问到字符串中不存在的角标时,会发生StringIndexOutOfBoundsException。
// 根据字符获取索引
sop(str.indexOf('m', 3)); // 如果没有找到返回-1
// 反向索引一个字符出现的位置
sop(str.lastIndexOf("a"));
}
判断
boolean contains(str);
indexOf(str)
:可以索引str第一次出现的位置,如果返回-1,表示该str不在字符串中存在,所以,也可以用于对指定字符串判断是否包含,而且该方法既可以判断,又可以获取出现的位置。boolean isEmpty();
原理就是判断长度是否为0boolean startsWith(str);
boolean endsWith(str);
boolean equals(str);
boolean equalsIgnoreCase(str);
例,
public static void sop(Object obj) {
System.out.println(obj);
}
public static void method_is() {
String str = "ArrayDemo.java";
// 判断文件名称是否是以Array单词开头
sop(str.startsWith("Array"));
// 判断文件名称是否是.java文件
sop(str.endsWith(".java"));
// 判断文件名称是否包含Demo
sop(str.contains("Demo"));
}
转换
String(char[])
String(char[], offset, count);
将字符数组中的一部分转成字符串 ,count是个数static String copyValueOf(char[]);
static String copyValueOf(char[] data, int offset, int count);
static String valueOf(char[]);
char[] toCharArray();
String(byte[]);
String(byte[], offset, count);
将字节数组中的一部分转成字符串byte[] getBytes();
static String valueOf(int);
static String valueOf(double);
例,
3+""; // String.valueOf(3); int--->String
public static void sop(Object obj) {
System.out.println(obj);
}
public static void method_trans() {
char[] arr = {'a','b','c','d','e','f'};
String s = new String(arr,1,3);
sop("s="+s);
String s1 = "zxcvbnm";
char[] chs = s1.toCharArray();
for (int x = 0; x < chs.length; x++) {
sop("chs="+chs[x]);
}
}
特殊:字符串和字节数组在转换过程中,是可以指定编码表的。
替换
String replace(oldchar, newchar);
例,
public static void sop(Object obj) {
System.out.println(obj);
}
public static void method_replace() {
String s = "hello java";
// String s1 = s.replace('q', 'n'); // 如果要替换的字符不存在,返回的还是原串
String s1 = s.replace("java", "world");
sop("s="+s);
sop("s1="+s1);
}
切割
String[] split(regex);
例,
public static void sop(Object obj) {
System.out.println(obj);
}
public static void method_split() {
String s = "zhangsan,lisi,wangwu";
String[] arr = s.split(",");
for (int x = 0; x < arr.length; x++) {
sop(arr[x]);
}
}
子串。获取字符串中的一部分
String substring(begin);
String substring(begin, end);
例,
public static void sop(Object obj) {
System.out.println(obj);
}
public static void method_sub() {
String s = "abcdef";
sop(s.substring(20)); //从指定位置开始到结尾,如果角标不存在,会出现字符串角标越界异常
sop(s.substring(2,4));//包含头,不包含尾。获取整个字符串:s.substring(0, s.length());
}
转换,去除空格,比较
String toUpperCase();
String toLowerCase();
String trim();
int compareTo(String);
例,
public static void sop(Object obj) {
System.out.println(obj);
}
public static void method_7() {
String s = " Hello Java ";
sop(s.toLowerCase());
sop(s.toUpperCase());
sop(s.trim());
String s1 = "a1c";
String s2 = "aaa";
sop(s1.compareTo(s2));
}
练习一、模拟一个trim()方法,去除字符串两端的空格。
解:
思路:
代码如下:
public class StringTest {
public static void sop(String str) {
System.out.println(str);
}
public static String myTrim(String str) {
int start = 0, end = str.length()-1;
while(start <= end && str.charAt(start) == ' ')
start++;
while(start <= end && str.charAt(end) == ' ')
end--;
return str.substring(start, end+1);
}
public static void main(String[] args) {
String s = " ab cd ";
sop("("+s+")");
s = myTrim(s);
sop("("+s+")");
}
}
练习二、将一个字符串进行反转。将字符串中指定的部分进行反转,"abcdefg"--->"abfedcg"
。
解:
思路:
代码如下:
class StringTest {
public static void sop(String str) {
System.out.println(str);
}
public static String reverseString(String s, int start, int end) {
// 字符串变成数组
char[] chs = s.toCharArray();
// 反转数组
reverse(chs, start, end);
// 将数组变成字符串
return new String(chs);
}
public static String reverseString(String s) {
return reverseString(s, 0, s.length());
}
private static void reverse(char[] arr, int x, int y) {
for (int start = x, end = y - 1; start < end; start++, end--) {
swap(arr, start, end);
}
}
private static void swap(char[] arr, int x, int y) {
char temp = arr[x];
arr[x] = arr[y];
arr[y] = temp;
}
public static void main(String[] args) {
String s = "ab cd ";
sop("("+s+")");
sop("("+reverseString(s)+")");
sop("("+reverseString(s, 0, 3)+")");
}
}
练习三、获取一个字符串在另一个字符串中出现的次数。例如,"kk"在"abkkcdkkefkkskk"出现的次数。
解:
思路:
代码如下:
class StringTest2 {
// 方式一
public static int getSubCount(String str, String key) {
int count = 0;
int index = 0;
while((index = str.indexOf(key)) != -1) {
sop("str="+str);
str = str.substring(index+key.length());
count++;
}
return count;
}
// 方式二
public static int getSubCount_2(String str, String key) {
int count = 0;
int index = 0;
while ((index = str.indexOf(key, index)) != -1) {
sop("index="+index);
index = index + key.length();
count++;
}
return count;
}
public static void main(String[] args) {
String str = "kkabkkcdkkefkks";
// sop("count======"+str.split("kk").length); // 字符串"kkabkkcdkkefkks"第一次按照"kk"分隔,会生成数组{"", "abkkcdkkefkks"},所以不建议使用split()方法
sop("count="+getSubCount_2(str, "kk"));
}
public static void sop(String str) {
System.out.println(str);
}
}
练习四、获取两个字符串中最大相同子串。例如,"abcwerthelloyuiodef"和"cvhellobnm"。
解:
思路:
代码如下:
class StringTest3 {
public static String getMaxSubString(String s1, String s2) {
String max = "", min = "";
max = (s1.length() > s2.length()) ? s1 : s2;
min = (max == s1) ? s2 : s1;
// sop("max="+max+"...min="+min);
for (int x = 0; x < min.length(); x++) {
for (int y = 0, z = min.length() - x; z != min.length() + 1; y++, z++) {
String temp = min.substring(y, z);
// sop(temp);
if(max.contains(temp))
return temp;
}
}
return "";
}
public static void main(String[] args) {
String s1 = "abcwerthelloyuiodef";
String s2 = "cvhellobnm";
sop(getMaxSubString(s2, s1));
}
public static void sop(String str) {
System.out.println(str);
}
}
StringBuffer是字符串缓冲区,是一个容器。
特点:
toString()
变成字符串C(create)
U(update)
R(read)
D(delete)
StringBuffer append();
---将指定的数据作为参数添加到已有数据的结尾处StringBuffer insert(index, data);
---可以将数据插入到指定index位置
public static void sop(String str) {
System.out.println(str);
}
public static void method_add() {
StringBuffer sb = new StringBuffer();
sb.append("abc").append(true).append(34); // 方法调用链
// StringBuffer sb1 = sb.append(34);
// sop("sb==sb1:"+(sb == sb1));
sb.insert(1, "qq");
sop(sb.toString()); // aqqbctrue34
// sop(sb1.toString());
}
StringBuffer delete(start, end);
---删除缓冲区中的数据,包含start,不包含endStringBuffer deleteCharAt(index);
---删除指定位置的字符
public static void sop(String str) {
System.out.println(str);
}
public static void method_delete() {
StringBuffer sb = new StringBuffer("abcde");
// sb.delete(1, 3);
// 清空缓冲区
// sb.delete(0, sb.length());
// sb.delete(2, 3);
sb.deleteCharAt(2);
sop(sb.toString());
}
char charAt(int index);
int indexOf(String str);
int lastIndexOf(String str);
int length();
String substring(int start, int end);
StringBuffer replace(start, end, string);
void setCharAt(int index, char ch);
public static void sop(String str) {
System.out.println(str);
}
public static void method_update() {
StringBuffer sb = new StringBuffer("abcde");
// sb.replace(1, 4, "java");
sb.setCharAt(2, 'k');
sop(sb.toString());
}
StringBuffer reverse();
void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin);
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("abcdef");
char[] chs = new char[6];
sb.getChars(1, 4, chs, 1);
for (int x = 0; x < chs.length; x++) {
sop("chs["+x+"]="+chs[x]+";");
}
}
public static void sop(String str) {
System.out.println(str);
}
JDK1.5版本之后,出现了StringBuilder
。
StringBuffer与StringBuilder的区别:
StringBuffer
是线程同步的StringBuilder
是线程不同步的将StringBuilder
的实例用于多个线程时是不安全的。如果需要这样的同步,则建议使用StringBuffer
。
注意:以后开发,建议使用StringBuilder。
升级三个因素:
基本数据类型包装类的最常见作用:就是用于基本数据类型和字符串类型之间做转换。
基本数据类型的包装类.toString(基本数据类型值)
Integer.toString(34);// 将整数34变成字符串"34";
xxx a = Xxx.parseXxx(String);
int a = Integer.parseInt("123");
double b = Double.parseDouble("12.23");
boolean b = Boolean.parseBoolean("true");
// 还有一种形式:
Integer i = new Integer("123");
int num = i.intValue();
// 将一个字符串转成整数
int num = Integer.parseInt("a123");//NumberFormatException,必须传入数字格式的字符串
System.out.println("num="+(num+4));
toBinaryString();
toHexString();
toOctalString();
System.out.println(Integer.toBinaryString(6));
System.out.println(Integer.toBinaryString(-6));
System.out.println(Integer.toHexString(60));
parseInt(String, radix);
int x = Integer.parseInt("3c", 16);
sop("x="+x);
JDK1.5版本以后出现的新特性——装箱与拆箱
JDK1.5以后,简化了定义方式:如
Integer x = new Integer("4");
可以直接写成:
Integer x = 4; // 自动装箱
接着自动拆箱:
x = x /*x.intValue()*/ + 2; // x+2:x进行了自动拆箱,变成了int类型,和2进行加法运算,再将和进行装箱赋给x
需要注意:在使用时,Integer x = null;
上面的代码就会出现NullPointerException
。
面试题:以下代码会输出什么?
class IntegerDemo {
public static void sop(String str) {
System.out.println(str);
}
public static void main(String[] args) {
Integer m = 128;
Integer n = 128;
sop("m==n:"+(m==n));
Integer a = 127;
Integer b = 127;
sop("a==b:"+(a==b));
}
}
答:false
和true
。
解析:
Integer m = 128;
Integer n = 128;
sop("m==n:"+(m==n)); // false,因为m和n指向了不同Integer对象,
Integer a = 127;
Integer b = 127;
// 结果为true。因为a和b指向了同一个Integer对象,
// 因为当数值在byte范围内时,对于新特性,如果该数值已经存在则不会再开辟新的空间
sop("a==b:"+(a==b));