赶鸭子Java_java乱炖

---------------------------------------------------------

ArrayList arrayList = new ArrayList(10);

System.out.println(arrayList.size());

大家猜,打印结果会是什么?会是10吗?

答案:0

因为,new ArrayList(10),只是告诉jvm分配10个Stirng的空间出来,arrayList 不是null而已。此时的arrayList 无任何内容!

---------------------------------------------------------

为什么说JDK中处理String的indexOf()方法效率低,建议不要使用?  今天探了个究竟。

上源码!

static int indexOf(char[] source, int sourceOffset, intsourceCount,char[] target, int targetOffset, inttargetCount,intfromIndex) {if (fromIndex >=sourceCount) {return (targetCount == 0 ? sourceCount : -1);

}if (fromIndex < 0) {

fromIndex= 0;

}if (targetCount == 0) {returnfromIndex;

}char first =target[targetOffset];int max = sourceOffset + (sourceCount -targetCount);for (int i = sourceOffset + fromIndex; i <= max; i++) {/*Look for first character.*/

if (source[i] !=first) {while (++i <= max && source[i] !=first);

}/*Found first character, now look at the rest of v2*/

if (i <=max) {int j = i + 1;int end = j + targetCount - 1;for (int k = targetOffset + 1; j < end &&source[j]== target[k]; j++, k++);if (j ==end) {/*Found whole string.*/

return i -sourceOffset;

}

}

}return -1;

}

真整齐啊!

上来就看到了两个for循环。问题必然出在这里!和KMP算法不同,这明显是简单粗暴的loop index。为什么没采用复杂度为O(m+n)的KMP算法?估计时间问题吧。

以后注意尽量避免indexOf()方法。

顺便窥探了下subString()方法的实现:

上源码!

public String substring(intbeginIndex) {if (beginIndex < 0) {throw newStringIndexOutOfBoundsException(beginIndex);

}int subLen = value.length -beginIndex;if (subLen < 0) {throw newStringIndexOutOfBoundsException(subLen);

}return (beginIndex == 0) ? this : newString(value, beginIndex, subLen);

}public String(char value[], int offset, intcount) {if (offset < 0) {throw newStringIndexOutOfBoundsException(offset);

}if (count < 0) {throw newStringIndexOutOfBoundsException(count);

}//Note: offset or count might be near -1>>>1.

if (offset > value.length -count) {throw new StringIndexOutOfBoundsException(offset +count);

}this.value = Arrays.copyOfRange(value, offset, offset+count);

}

怪不得效率较高,原来用到了Arrays.copyOfRange()方法。

---------------------------------------------------------

一道非常老的面试题:

从字符串str1中找出子字符串str2出现的次数。比如:

String str1 = "sgiccomcocmcomomameadjcomfjecomcomcomcijr";

String str2= "com";

自己想到的方法如下:

//暴力匹配//KMP算法//subString//split//RegEx(may be the best)

这其中,RegEx(正则匹配)的效率是最高的(个人理解)。而且实现起来也很简单,如下:

String str1 = "sgiccomcocmcomomameadjcomfjecomcomcomcijr";

String str2= "com";int times = 0;

Pattern pattern=Pattern.compile(str2);

Matcher matcher=pattern.matcher(str1);while(matcher.find()) {

times++;

System.out.println(matcher.group());

}

System.out.println(times);

---------------------------------------------------------

7/30

刚刚正在探索KMP算法,然后有经验的同事过来看看究竟。不过扯出了另外一个话题,正则的效率不一定高!用他的话说,java代码需要JVM进行解释,那正则表达式也是需要解释器的(可以这么理解),所以效率很可能会低的。

另外,String类中也存在matches()方法,遂对该方法和Pattern中的matches()进行了对比。

代码如下:

public static voidmain(String[] args){

String string= "ddenfj#@fe_dw.comw";int count = 100000;long before =System.currentTimeMillis();

Runtime runtime=Runtime.getRuntime();long r1 =runtime.totalMemory();for (int i = 0; i < count; i++) {

string.matches("^([\\.a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\\.[a-zA-Z0-9_-]{2,3}){1,2})$");

}long r2 =runtime.totalMemory();long end =System.currentTimeMillis();

System.out.println("the memory of match() in String is = " + (r2-r1)/1024);

System.out.println("the time of match() in String is = " + (end-before));//Pattern

Pattern pattern = Pattern.compile("^([\\.a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+((\\.[a-zA-Z0-9_-]{2,3}){1,2})$");

before=System.currentTimeMillis();

r1=runtime.totalMemory();for (int i = 0; i < count; i++) {

pattern.matcher(string).matches();

}

r2=runtime.totalMemory();

end=System.currentTimeMillis();

System.out.println("the memory of match() in Pattern is = " + (r2-r1)/1024);

System.out.println("the time of match() in Pattern is = " + (end-before));

}

在count=100000的情况下,发现结果如下:

the memory of match() in String is = 92416the time of match() in String is= 327the memory of match() in Pattern is= 0the time of match() in Pattern is= 26

结果让我吃惊!String类中的matches()方法相对于Pattern类中的matches()方法,简直不能用!

究其原因:String类中的matches()方法调用了Pattern.matches(regex, this),而该方法的实现如下:

public static booleanmatches(String regex, CharSequence input) {

Pattern p=Pattern.compile(regex);

Matcher m=p.matcher(input);returnm.matches();

}

强调部分的重复执行会占用大量内存。

而且该方法的解释中:If a pattern is to be used multiple times, compiling it once and reusing it will be more efficient than invoking this method each time.

总之,String类中的matches()方法不要使用!

---------------------------------------------------------

今天同事问了个问题:不同版本的jar包,能同时存在吗?如果能的话,应该加载的哪个?

做了个实验,把poi-3.10-beta2.jar和poi-3.10-FINAL.jar(我把名称改为chris.jar)放在lib文件夹下,编译没错,证明可以共存。

但是使用哪个jar包呢?最新的。怎么区分最新的?根据版本号?

最后证明编译器仍然使用chris.jar下的class文件。

结论:当不同版本的jar包共存时,编译器将根据class的时间以及META-INF下的信息区分哪个jar包是最新的,并加载之。

---------------------------------------------------------

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值