首字母大写(求更快的写法)

fog. 发布于 2012/06/18 17:45
阅读 9K+
收藏 1

以下是对一个字符串首字母进行大写的三个片段:

想问下,各位大牛,还有没有更快的写法?

/**
	 * 1.用了8秒
	 * @param str
	 * @return 
	 */
	public static String firstLetterToUpper(String str){
		char[] array = str.toCharArray();
		array[0] -= 32;
		return String.valueOf(array);
	}
	
	/**
	 * 2.用了10秒
	 * @param str
	 * @return 
	 */
	public static String lcy_firstLetterToUpper(String str){
		return String.valueOf(str.charAt(0)).concat(str.substring(1));
	}
	/**
	 * 3.用了11秒
	 * @param str
	 * @return 
	 */
	public static String letterToUpper(String str){
		Character c = Character.toUpperCase(str.charAt(0));
		return c.toString().concat(str.substring(1));
	}
	
	public static void main(String[] args) {
		long millis = System.currentTimeMillis();
		for(int i = 0 ; i < 29999999;i++){
			firstLetterToUpper("s121fdfs"+i);
		System.out.println((System.currentTimeMillis() - millis)/1000 + "秒");
		}
	}

写代码的时候,不该纠结这问题.

但禁不住,还是想问下?

加载中
0
实迷途其未远觉今是而昨非
实迷途其未远觉今是而昨非

lz电脑nb啊,我用自己电脑跑了下,你8秒的我跑了273秒,e5700的u

用线程池会不会快点?

实迷途其未远觉今是而昨非
实迷途其未远觉今是而昨非
回复 @foggy : 我前面的回复没看到你的这个回复,oschina的@提醒有点慢
fog.
fog.
System.out.println((System.currentTimeMillis() - millis)/1000 + "秒"); 搞错了,,不好意思.. 你把这句丢出for循环来..
0
红薯
红薯
commons-lang 包的 StringUtils 有个方法 capitalize 可以尝一下
fog.
fog.
public static String firstLetterToUpper3(String str){ return StringUtils.capitalize(str); } @红薯 这个我这边,是10秒.
0
实迷途其未远觉今是而昨非
实迷途其未远觉今是而昨非
firstLetterToUpper("s121fdfs"+i);

System.out.println((System.currentTimeMillis() - millis)/1000 "秒");


还有我觉得lz的循环里面拼接字符串的操作可能会影响对大写耗时的统计,循环里面直接拼接字符串有陷阱,编译器要创建非常多的stringBuilder对象来拼接你的字符串,再返回string类型,thinginginjava里面提到过这个问题

0
实迷途其未远觉今是而昨非
实迷途其未远觉今是而昨非
lz你的程序跑了2遍我的电脑卡住了,我恨你。。。
0
实迷途其未远觉今是而昨非
实迷途其未远觉今是而昨非

lz字符串的拼接+ms的除法占了大部分时间

循环里面改成这样

 firstLetterToUpper("s121fdfs");

下面这个放到循环外面,只需要1秒,lz原来的需要280秒左右

System.out.println((System.currentTimeMillis() - millis)/1000 + "秒");

 

就算把循环里面的改成lz原来的

firstLetterToUpper("s121fdfs"+i);

也只需要7秒左右

实迷途其未远觉今是而昨非
实迷途其未远觉今是而昨非
回复 @foggy : 你主要是拼字符串耗时哎,转换大小写远小于拼字符串耗费的时间
fog.
fog.
嗯.这个会去掉的.
0
Jeky
Jeky

特殊情况 特殊处理吧 虽然这个可不是常规编程方案....

import java.lang.reflect.Field;

public class Test {
	/**
	 * 1.用了8秒
	 * @param str
	 * <a href="http://my.oschina.net/u/556800" class="referer" target="_blank">@return</a> 
	 */
	public static String firstLetterToUpper(String str){
		char[] array = str.toCharArray();
		array[0] -= 32;
		return String.valueOf(array);
	}
	
	/**
	 * 2.用了10秒
	 * @param str
	 * <a href="http://my.oschina.net/u/556800" class="referer" target="_blank">@return</a> 
	 */
	public static String lcy_firstLetterToUpper(String str){
		return String.valueOf(str.charAt(0)).concat(str.substring(1));
	}
	/**
	 * 3.用了11秒
	 * @param str
	 * <a href="http://my.oschina.net/u/556800" class="referer" target="_blank">@return</a> 
	 */
	public static String letterToUpper(String str){
		Character c = Character.toUpperCase(str.charAt(0));
		return c.toString().concat(str.substring(1));
	}
	
	public static void main(String[] args) {
		try {
			stringField = String.class.getDeclaredField("value");
			stringField.setAccessible(true);
		} catch (Exception e){
			e.printStackTrace();
		}
		
		long millis = System.currentTimeMillis();
		for(int i = 0 ; i < 29999999;i++){
			String string = hackCap("abc" + i);
		}
		System.out.println((System.currentTimeMillis() - millis)/1000 + "秒");
		

		millis = System.currentTimeMillis();
		for(int i = 0 ; i < 29999999;i++){
			String string = firstLetterToUpper("abc" + i);
		}
		System.out.println((System.currentTimeMillis() - millis)/1000 + "秒");
	}

	private static String hackCap(String string) {
		try {
			char[]  value = (char[]) stringField.get(string);
			value[0] -= 32;
			
			return string;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return string;
	}
	
	private static Field stringField;
}

canghailan
canghailan
而且我觉得反射修改也不一定比new更快(其实个人感觉是不可能更快,待验证)。
canghailan
canghailan
这么弄有些情况会出问题啊!JDK里字符串的第一个字符应该是value[offset]。直接更新value数组可能会导致String的hash缓存值与更新后实际值不匹配。 修改String这种不可变对象,一次字符数组复制是必须的,分配数组也不昂贵,所以我觉得常规做法已经很好了。
0
中山野鬼
中山野鬼
看不懂,你们在优化什么哦???? 怎么总觉得这种代码特别适合测试C++的优化编译能力,而不是自己的代码设计能力。哈。
中山野鬼
中山野鬼
都是”求更快“害的。比速度,我只会想到C和 C++。其他语言没有比速度的必要。。。
中山野鬼
中山野鬼
我猪头了。貌似这个不是C++吧。哈。。。。。
0
canghailan
canghailan

这个再怎么样也慢不到那去,没必要追求什么更快。

public static String firstLetterToUpper(String string) {
	char[] buffer = string.toCharArray();
	buffer[0] = Character.toUpperCase(string.charAt(0));
	return new String(buffer);
}

你测试时间主要也不是这个方法消耗的。字符串拼接,输出消耗的时间比你要测试的方法消耗的更多,你这个测试是测不准的。

String是不可变对象,所以常规方法一次字符数组复制,首字符大写,根据字符数组构建新字符串对象这三个操作是必须的,能避开的只是额外的诸如构建StringBuilder对象等的开销。

0
水牛叔叔
水牛叔叔

这样写怎样:

"string".substring(0, 1).toUpperCase()+"string".substring(1)



0
longteng556
longteng556

经过测试,最快的方法实现是:

public static void main(String[] args) {
		long now = System.currentTimeMillis();
		for (int i = 0; i < 100000000; i++) {
			firstLetterUpper1("name");
		}
		System.out.println((System.currentTimeMillis()-now));
	}

	public static String firstLetterUpper1(String text) {
		return text.replace(text.charAt(0),((char)(text.charAt(0)-32)));
	}

一亿次的计算:1764 ms.



返回顶部
顶部