JAVA入门教程:(八)String、StringBuilder与API

上一章,初步了解了String对象,知道它能用来定义一个字符串变量,本章主要学习String、StringBuilder的方法,以及如何通过API来查找对象和方法的用法。

先来了解下String中常用的方法:

public class Test {
	
	public static void main(String[] args) {
		
		String str = "  123456aBCDef哈哈  "; //定义一个字符串变量
		
		System.out.println(str.charAt(6)); //返回指定索引处的char值
		System.out.println(str.indexOf("6a")); //返回指定子字符串在此字符串中第一次出现处的索引。
		System.out.println(str.indexOf("6a1")); //返回指定子字符串在此字符串中第一次出现处的索引。不存在时返回-1
		System.out.println(str.startsWith("123")); //测试此字符串是否以指定的前缀开始。
		System.out.println(str.endsWith("e")); //测试此字符串是否以指定的前缀结束。
		System.out.println(str.length()); //返回此字符串的长度
		System.out.println(str.replaceAll("6a", "!!!")); //用!!!替换6a,第一个参数为正则表达式
		System.out.println(str.substring(3, 10)); //截取指定范围索引的字符串
		System.out.println(str.toLowerCase()); //转小写
		System.out.println(str.toUpperCase()); //转大写
		System.out.println(str.trim()); //前后去空格、回车等不可见字符
		
		System.out.println("---------------------------------------");
		String arr[] = "abc,123,sss,666,sisia9".split(","); //根据匹配给定的正则表达式来拆分此字符串返回数组。
		for (int i = 0; i < arr.length; i++) {
			System.out.println(arr[i]);
		}
	}
}

这些方法非常常用,假如我们在使用一个对象时,不知道它里面有哪些方法可以被我们使用,就需要通过查询API帮助文档来获取对象的使用方法。

下载一个JDK_API_1_6_zh_CN.CHM。https://pan.baidu.com/s/1XwtYFaytZFi_YX1pPd6qeg

,打开之后点“显示”,然后点“索引”,输入“String”,按回车,选择第一个,之后就是如下界面:

然后往下翻,找到摘要方法,选一个你想了解的方法,如charAt,点击进去

public char charAt(int index),可以看到该方法的返回值以及传参类型:返回一个char型字符,需要传入一个int型的值,文档里面写的都很清楚,遇到不会的方法就多查API就对了。

下面的内容很重要

下面是定义String的两种方式

public class Test {

	public static void main(String[] args) {
		
		String str1 = "我是一个字符串"; //第一种方式
		String str2 = "我是一个字符串";
		String str3 = new String("我是一个字符串"); //第二种方式

		System.out.println("str1==str2 " + (str1 == str2));
		System.out.println("str1==str3 " + (str1 == str3));
	}
}

运行之后,能看到用三个变量定义同一个字符串,str1等于str2,str1不等于str3,为什么呢?

我们定义字符串对象str3时候会把str3对象保存在里,把堆的引用保存在里,如图:

绝大多数对象的创建就是这么个过程

但是字符串对象是个例外,他还维护了一个字符串常量池,如在定义str1时,他先在常量池种找有没有“我是一个字符串”,(1)如果没有就创建一个,然后在栈中建一个str1并保存常量池的引用。(2)如果有就直接在栈中建一个str1,然后在栈中建一个str1并保存常量池的引用。str2同上。对于str3的定义方式,因为使用了new关键字,就一定会在中创建一个对象,存在一个一对一的关系,然后常量池也会创建一个对象(如果这个对象“我是一个字符串”已存在,就不创建了,直接指向就可以了)。str1和str2的创建是一对多的关系。

我们用“==”比较对象时,是比较对象的引用(或理解为对象的地址),如上图所示,str1和str2都是指向常量池中的同一个对象,所以他们的引用相同,返回true,str3是在中新建了一个对象,与str1的引用不相同,所以返回false。面试题中经常会问String str = new String("abc")创建了几个对象,答案是:两个,一个在堆中,一个在常量池中。

那么,我们应该怎么比较字符串呢?String给我们提供了一个方法:equals(),专门用来比较字符串中的指,而非比较地址。代码如下:

public class Test {

	public static void main(String[] args) {
		
		String str1 = "我是一个字符串";
		String str2 = "我是一个字符串";
		String str3 = new String("我是一个字符串");

		System.out.println("str1==str2 " + str1.equals(str2));
		System.out.println("str1==str3 " + str1.equals(str3));
		System.out.println("123".equals("321"));
	}
}		System.out.println("123".equals("321"));
	}
}

同理,我们定义一个字符串之后,每次改变值时,也会有一个查找或创建常量池的过程,这个过程会有一定的耗时,假如你频繁的改变str1值或者一直追加str1值的时候,使用String类就不划算了。下面代码可以得出这个结论:

public class Test {

	public static void main(String[] args) {
		
		String str1 = "";
		long begin = System.currentTimeMillis();
		
		for (int i = 0; i < 10000; i++) {
			str1 = str1 + i;
		}
		
		long end = System.currentTimeMillis();
		
		System.out.println("用时:" + (end - begin));
	}
}

 

 

给str1追加一万次和十万次所用的时间相差还是比较大的,一个0.189秒,一个32秒多。

这个时候我们就可以用StringBuilder来解决。StringBuilder是也是对字符串操作的一个对象,只不过他改变值或追加值的时候不会改变对象的引用,所以效率就很快。

public class Test {

	public static void main(String[] args) {
		
		StringBuilder sb = new StringBuilder();
		long begin = System.currentTimeMillis();
		
		for (int i = 0; i < 100000; i++) {
			sb.append(i);
		}
		
		long end = System.currentTimeMillis();
		
		System.out.println("用时:" + (end - begin));
	}
}

十万次的追加只用了0.04秒。

StringBuilder的一般用法:

public class Test {

	public static void main(String[] args) {
		
		StringBuilder sb1 = new StringBuilder();
		sb1.append("我");
		sb1.append("是");
		sb1.append("一个");
		sb1.append("字符串").append("哦也").append("!!!");// 看,它也可以连续.出来。
		System.out.println(sb1.toString());
		
		//他其实更适合用在多次循环中,循环次数也多效率体现的越明显(与String相比)
		StringBuilder sb2 = new StringBuilder();
		for (int i = 0; i < 2; i++) {
			if (i == 0) {
				for (int j = 0; j < 26; j++) {
					sb2.append((char)(j + 97)).append(" ");
				}
			}
			else {
				sb2.append("\r\n");
				for (int j = 0; j < 26; j++) {
					sb2.append((char)(j + 65)).append(" ");
				}
			}
		}
		
		System.out.println(sb2.toString());
	}
}

数字与字符互转相见百度百科:https://baike.baidu.com/item/ASCII/309296?fr=aladdin&fromid=19660475&fromtitle=ascii%E7%A0%81%E8%A1%A8

StringBuilder中的其他常用方法自行查看API即可。

 

 

上节作业答案:

public class C {
	
	int c = 4;
	
	public int c (int num) {
		return c * num;
	}
}

 

public class B {
	
	float b = 23.432f;
	
	public void b() {
		C c = new C();
		int num = c.c(618);
		System.out.println(num);
	}
}

 

public class A {

	public static void main(String[] args) {
		
		B b = new B();
		System.out.println(b.b);
		b.b();
	}

}

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值