??xml version="1.0" encoding="utf-8" standalone="yes"?>97久久精品视频,免费在线观看成人,日本中文字幕视频一区http://www.aygfsteel.com/xiaofei-suman/category/36461.htmlzh-cnTue, 13 Mar 2012 07:31:18 GMTTue, 13 Mar 2012 07:31:18 GMT60StringBuilder部分源码阅读http://www.aygfsteel.com/xiaofei-suman/articles/370974.html齐纳多齐纳多Wed, 29 Feb 2012 03:01:00 GMThttp://www.aygfsteel.com/xiaofei-suman/articles/370974.htmlhttp://www.aygfsteel.com/xiaofei-suman/comments/370974.htmlhttp://www.aygfsteel.com/xiaofei-suman/articles/370974.html#Feedback0http://www.aygfsteel.com/xiaofei-suman/comments/commentRss/370974.htmlhttp://www.aygfsteel.com/xiaofei-suman/services/trackbacks/370974.html阅读全文

齐纳多 2012-02-29 11:01 发表评论
]]>
转帖-String详解?intern隐士http://www.aygfsteel.com/xiaofei-suman/articles/370843.html齐纳多齐纳多Mon, 27 Feb 2012 06:53:00 GMThttp://www.aygfsteel.com/xiaofei-suman/articles/370843.htmlhttp://www.aygfsteel.com/xiaofei-suman/comments/370843.htmlhttp://www.aygfsteel.com/xiaofei-suman/articles/370843.html#Feedback0http://www.aygfsteel.com/xiaofei-suman/comments/commentRss/370843.htmlhttp://www.aygfsteel.com/xiaofei-suman/services/trackbacks/370843.html

    转帖地址Q?a >http://congmo.github.com/blog/2012/02/16/1-translationofstring/(葱末)

       规范化的字符串可节省I间Q代价就是花Ҏ多的CPU旉来检存储在RAM中的字符串和替换字符串副本。规范化之后的字W串Q不论存在多引用,仅在RAM中存在一份。由于String是不可变的,所以比如两个不同的Ҏy使用同一个字W串Q那么它们就可以使用同一个String的副本。不论字W串的意思在不同的语境下是否相同Q依旧可以共享,好比sin可以是h名,当然也是三角函数中的函数名。共享重复字W串的过E就叫做规范化。String.intern()q回规范化的dW串的引用。规范化之后的字W串可以直接使用==(比较引用)来比较两个字W串是否相等。由于String不可变的Ҏ,可以节省很多I间。比?#8221;pot”?#8221;hippopotamus”中出玎ͼ那么׃需要创建新的字W串Q额外分配新的空?堆中的空?Q返回一个相应指?#8221;hippopotamus”的引用即可?/p>

Z要规范化

规范化字W串有如下两个原因:

  • 通过去除字符串字面值副本来节省I间(也就是字W串值在ҎZ只有一份,其他全部是指向它的引??/li>
  • 使字W串比较变的很快。即使用equals比较规范化后的字W串也要快很多?

    比如,文件中用逗号分隔?0000人的党籍dHashMapQ那么内存中需?0000左右个字W串用来记录q些党籍。如果将字符串进行规范化Q那么几十个p矣?/p>

    规范化与String.substring()

    使用String.substring()ӞJVM只在栈中分配一个Stringcd的引用,指向原始字符串的字面倹{substring不需要额外分配空_也不需要拷贝字W。String.substring不会对结果进行规范化?/p>

    注意Q只要还?#8221;zd”的子串指向原始字W串Q那么垃圑֛收期没法回收它?/p>

    String.subString产生的空串也不用自动规范化,因此Q空串也会导致长长的原始字符串没法被回收?/p>

    1 public static void main(String args[]){
    2         String s = "a very long string";
    3         // create an empty substring
    4         String e1 = s.substring( 0,0);
    5         // make sure the empty string is canonical
    6         String e2 = ( e1.length() ==0) ? "" :e1;
    7         System.out.println( e1=="" );// always prints false
    8         System.out.println( e2=="" );// always prints true   
    9 }
    

    规范化与void字符?/h3>

    惌避免IZ致原始字符串不能被回收Q就不要使用Mvoid字符串指向原始字W串。void字符串有3中:””,” “,null?/p>

     1 public final static String possiblyEmpty( StringpString)
     2 {
     3    if( pString==null) return"";
     4    pString=pString.trim();
     5    if( pString.length() ==0) return"";
     6    returnpString;
     7 }
     8 public final staticStringpossiblyNull( StringpString)
     9 {
    10    if( pString==null) returnnull;
    11    pString=pString.trim();
    12    if( pString.length() ==0) returnnull;
    13    returnpString;
    14 }
    15 public final staticStringneverNull( StringpString)
    16 {
    17    /* if pString is null, Java will throw an NullPointerException */
    18    pString=pString.trim();
    19    /* if pString is empty or blank, throw a NullPointerException */
    20    if( pString.length() ==0) throw newNullPointerException();
    21    returnpString;
    22 }
    

    规范化疑难杂?/h3>

    所有字W串在编译期间被规范化,那么E序q行时生的字符串就不能被规范化。这h较恶心的一Ҏ在大多数情况下程序可以正常运行,但是在特D的情况下就会出错。就比如Q?=替代equals来比较两个字W串是否相等Q绝大多数是可行的,因ؓ字符串会被规范化Q但是不排除特例Q比如运行期间生的字符丌Ӏ?/p>

    规范化与new String( String )

    新手喜欢用String s = new String( “hello” );代替String s = “hello”;

    q与规范化正好相反,q样创徏了一个全新的”hello”字符Ԍ虽然有相同的字面|但是不会被规范化。在两种场景下适合使用new来创建字W串Q?/p>

  • 预得C个唯一的字W串同步对象?/li>
  • Z不引用庞大的原始字符丌Ӏ用new来创建字W串Q就可以使原始字W串被回收。如果只有几个很短的子串包含在一个庞大的字符串中Q这时用new来创建新的字W串是值得的。当然如果有众多的子串都要指向一个母Ԍ没有必要这样做了?

    使用new String( String )׃定会创徏一个全新的字符串吗Q答案是肯定的。你可能以ؓJVM很智能,会将新创建的字符串规范化Q然后返回指向母串的引用。但是语a规范中指出,new String()一定会创徏一个全新的字符Ԍ管JVM在理Z可以同String.substring(0)和String.intern.substring(0)一栯行规范化Q防止出现多个拷贝?/p>

    q就引申出另外一个问题,s == s.substring(0)Lq回false吗?{案也是肯定的?/p>

    q有一个适合用new来创建字W串的地方,如下Q?/p>

    1 String password = new String( jpassword.getPassWord() );
    

    getPassWordҎq回一个字W数l?char)Q这么做q不愚蠢Q在高安全性的场景下,可以将char数组清空?/p>

    看下q段代码QString s = new String( “Hello” ); 当变量s所在的c被加蝲的时候,字面?#8221;Hello”会被规范化,但是愚蠢的用new StringQ会在堆中重新创Z份字面?#8221;Hello”Q地址与规范化后的”Hello”不同。在Sun的JVM中,规范化的字符串被存储在一个叫perm gen的特DRAM区域Q这个区域中JVM也加载类和存储本地编译后的代码,而且规范化后的字W串与存储在堆中的普通对象一栗如果这样写QString s = “Hello”Q就不会重新创徏”Hello”的副本,而是直接指向规范化后的字W串?/p>

    规范化与垃圾回收

    在JDK的早L本中Q由于JVM要持有存储规范化后字W串的HashTable的引用,以便查新创徏的字W串是否已在׃n池中存在Q这样就D了规范化后的字符串没法被垃圾回收器回收。随着1.2版本中引入了弱引用之后,无用的规范化字符串就可以被回收了?/p>

    JDK1.2版本之后Q规范化字符串在没用引用指向它时Q可以被回收Q而且规范化不是只发生在编译期。这样以~码的方式重新创建、规范化字符串时Q新创徏的字W串对象会变成唯一的原始字W串。这样做不会带来实际的问题,使用==来比较两个字W串包含的字W是否相{同样奏效?q里理解的不是很好,我觉得应该是q样的:同一个字面D范化后,之前的那个字面值的地址会被新地址替换?

    溢出

    java.lang.OutOfMemoryError: String intern table overflow 表示规范化字W串太多。一些低版本的JVM规定规范化字W串不能过64K(大约50000?。IBM的Java1.1.8 JRE有q样的限制。它是ErrorQ不是ExceptionQ如果想捕获它,可以q样做:

     1 public class InternTest
     2 {
     3         public static final intn=80000;
     4         public static void main( String[] args)
     5         {
     6                 String[] hold = new String[n];
     7                 // build list of interned strings
     8                 for( inti=0;i<n;i++)
     9                 {
    10                         try
    11                         {
    12                             hold[i] =Integer.toString(i).intern();
    13                         }
    14                         catch( Throwablee)
    15                         {
    16                             System.out.println( "intern exploded at " +i);
    17                             System.exit( 1);
    18                         }
    19                  }
    20                 // make sure they were really interned.
    21                 for( inti=0;i<n;i++)
    22                 {
    23                 if( hold[i] !=Integer.toString(i).intern() )
    24                 {
    25                     System.out.println( "intern failed at " +i);
    26                     System.exit( 1);
    27                 }
    28         }
    29               System.out.println( "intern good for at least " +n+" Strings." );
    30 }
    

    依旧要注意规范化?#8221;不利”垃圾回收?/p>

    底层

    q里只讲底层规范化如何v作用的最单Ş式。JVM内部在堆中存储对象,包括规范化与普通的String对象(q个说法貌似不是很严?。而且规范化的String被放在一?#8221;?#8221;HashMap中?/p>

    HashMap中的String集合Q也叫字W串帔R池。他们和堆中其他普通对象没什么两P只是因ؓl过优化后,生存期要长一些。String对象在堆中,而指向它的引用存在HashMap中,所以规范化字符串有自己的共享池?/p>

    当字W串被规范化Ӟ先在HashMap中检查是否已存在Q如果存在则q回指向dW串的引用,通常q个引用优先自n的引用,而自w的副本很快被垃圾回收器回收。如果没有,则将其引用添加到HashMap中,q注册ؓdW串。规范化的过E不会再生成字符串的副本Q只是持有主字符串的唯一引用?/p>

    规范化与非规范化的字W串都存储在堆中。由于规范化时生的是弱引用Q所以当除了HashMap中的弱引用再无其他引用指向主字符串时Q该dW串可以被回收了?/p>

    new StringӞ不会自动规范化,因此在堆中会有同一个字W串的多个副本。随后调用该字符串的internҎQ这些副本也不会被清除?/p>

    我L觉这里貌似有问题Q干脆不译了,把原文脓上吧?/p>

    This is a simplified version of how interning works under the hood. Inside the JVM is the heap where all allocated Objects reside. This includes Strings both interned and ordinary. (In Sun’s JVM, the interned Strings (which includes String literals) are stored in a special pool of RAM called the perm gen, where the JVM also loads classes and stores natively compiled code. However, the intered Strings behave no differently than had they been stored in the ordinary object heap.) In addition, interned Strings are registered in a weak HashMap.The collection of Strings registered in this HashMap is sometimes called the String pool. However, they are ordinary Objects and live on the heap just like any other (perhaps in an optimised way since interned Strings tend to be long lived). The String Object lives on the heap and a reference to it lives in the HashMap. There is so separate pool of interned String objects. Whenever a String is interned, it is looked up in the HashMap to see if it exists already. If so the user gets passed a reference to the master copy. Normally he will use that copy in preference to his. His duplicate copy then will likely soon have no references to it and will be eventually garbage collected. If the String has never been seen before, a reference to it will be added to the HashMap and intern will hand him a reference to his own String, now registered as the unique master. Note that the intern process does not make a copy of the String, it just keeps a reference to the unique master copies. All the Strings, interned and ordinary live on the heap. When there are no references left to a String except the intern HashMap registry reference, it will be garbage collected since intern keeps only a weak reference to it. When you say new String, it is not automatically interned. Thus there may then be duplicates on the heap. If you later use intern on that String, those duplicates won’t be cleaned up. Only when you intern all copies of a String, and discard references to the uninterned versions do you maintain but a single copy.

    手动规范?/h3>

    规范化最大的问题是知道E序l束才能销毁占用RAM的空_管再没有引用指向主字符Ԍ也不能被垃圾回收器回?早期版本)。如果想使用一个时的规范化字W串Q可以用手动规范化?/p>

    然而,现在L的JVM中的规范化字W串׃n池都是采用弱引用实现的,所以只要没有强引用指向dW串Q则可被垃圾回收器回收。你可以像JVM一P自己实现规范化的q程?/p>

    比如假设从文件中d以逗号分隔的h名与地址Qƈ以某U顺序存入集合,׃很多人居住在同一城市Q所以RAM中就会充满了同一个城市的副本?/p>

    那么创徏一个HashMap(不是HashSet),用于存储每个城市名称的主字符丌Ӏ每ơ获取城市时Q先从HashMap中查找,如果存在则用dW串的引用替换自w的引用。自wString对象的副本很快就会被垃圾回收器回收。如果不存在增加城市到HashMap?/p>

    当读完城市后Q就可以讲HashMap抛弃Q而放入到HashMap中的dW串Q除了没有其他引用指向的dW串被垃圑֛收器回收掉之外,q是一样存在,一h有唯一的引用,而且与规范化后的字符串一栗?/p>

    原文地址Q?a >http://mindprod.com/jgloss/interned.html



    q里q译完了Q不q有些地方觉得怪怪的。还有由于个人水q_在是有限Q难免有地方_糙。另外,如果你说研究q个实在是没有意思类似的话,那拜托你憋在心里吧,谢谢了?/p>

    因ؓ在看jdk源码Q看到String中最后一行的intern是个nativeҎQ于是就到处查资料,q在OSChina上提Z个问题:http://www.oschina.net/question/129471_38493Q讨Z提C撒加在javaeye上的一个帖子的回答Q?a >http://www.iteye.com/topic/1112592Q于是我做了如下的测试,又画?张图?/p>

    试环境Q?

    java version "1.6.0_17" Java(TM) SE Runtime Environment (build 1.6.0_17-b04) Java HotSpot(TM) Client VM (build 14.3-b01, mixed mode, sharing)

     

    1 public static void main(String[] args) {
    2         String str0 = "congmo.github.com";
    3         System.out.println(str0.intern() == str0);
    4 }
    
    输出l果Qtrue
    1 public static void main(String[] args) {
    2         String str0 = args[0];
    3         System.out.println(str0.intern() == str0);
    4 }
    
    同样在命令行输入:congmo.github.com
    输出l果Q?br />false
     1 public static void main(String[] args) {
     2 
     3         String str0 = "congmo.github.com";
     4         System.out.println(str0.intern() == str0);
     5                 
     6         String str1 = new String( args[0] );
     7         System.out.println(str1.intern() == str1);
     8 
     9         System.out.println(str0 == str1.intern());
    10 }
    
    输出l果Q?br />true
    false
    true

    从前面两D代码中可以看出Q用命令行的方式同栯入参?#8221;congmo.github.com”Q将args0赋值给str0Q然后str0.intern()==str0的结果竟然是falseQ难道真如javaeye那篇帖子中有人怀疑的那样QJVMargs0提前p范化了?按道理应该不会啊?/p>

    试环境Q?

    java version "1.7.0_02" Java(TM) SE Runtime Environment (build 1.7.0_02-b13) Java HotSpot(TM) Client VM (build 22.0-b10, mixed mode, sharing)

     

    1 public static void main(String[] args) {
    2         String str0 = args[0];
    3         System.out.println(str0.intern() == str0);
    4 }
    
    输出l果Q?true
    1 public static void main(String[] args) {
    2         String str0 = new String( args[0] );
    3         System.out.println(str0.intern() == str0);
    4 }
    
    输出l果Q?true
    1 public static void main(String[] args) {
    2         String str0 = args[0];
    3         System.out.println(str0.intern() == str0);
    4         String str = new String( args[0] );  
    5         System.out.println(str.intern() == str);
    6         System.out.println(str.intern() == str0);
    7 }
    
    输出l果Q?br />true
    false
    true

    但是?.7版本执行的结果看来,貌似可以定JVM没有对args0规范化,但是从javaeye帖子讨论中可以知?.7版本后perm genq个内存q掉了,所以规范化之后的字W串也存储在堆中Q所以无论args0有没有提前被规范化,str0始终都会指向堆中那个引用。按照我的理解,如下图所C:

    所以现在看来还是个未知数?/p>

    另外Q我按照自己的理解针?中情는?张图Q都是用于说明JVM的内存分配的?注:jdk1.6或之前版本,1.7之后Ҏ砍掉?/p>

    q两张图都是描述使用new创徏StringQ然后再调用自n的internҎ后内存以及引用的变化?/p>



  • 齐纳多 2012-02-27 14:53 发表评论
    ]]>
    转帖-String详解一:基础http://www.aygfsteel.com/xiaofei-suman/articles/370842.html齐纳多齐纳多Mon, 27 Feb 2012 06:49:00 GMThttp://www.aygfsteel.com/xiaofei-suman/articles/370842.htmlhttp://www.aygfsteel.com/xiaofei-suman/comments/370842.htmlhttp://www.aygfsteel.com/xiaofei-suman/articles/370842.html#Feedback0http://www.aygfsteel.com/xiaofei-suman/comments/commentRss/370842.htmlhttp://www.aygfsteel.com/xiaofei-suman/services/trackbacks/370842.htmlhttp://congmo.github.com/blog/2012/02/16/1-translationofstring/(葱末)

    译者注Q翻译这文章是有目的性的Q不是闲来无事打发时间。刚刚看完String的源码,虽然看完Q但是有很多东西(或者说”陷阱”)在源码中得不C现。可能是在编译器中进行了优化。无意中发现了这文章,里面讲述了一些隐含的Q源码中比较隐晦或者看不到的东ѝ比如substring,intern{。所以才有了译?#8221;动机”Q还有一专门讲qintern的,在之二中翻译。另Q翻译纯属个为,因技术与p水准有限Q文中肯定不乏欠妥之处,如果你能文明的指出,在下感Ȁ不尽。如a辞中满是不尊重,则请收回。希望能带给其大家帮助,以达共同q步之目的?/p>

    Java中的字符串不同于与C++中的字符Ԍ不能改动字符串中的字W。预查找字符串中某个字符Q可是用charAt()Ҏ。Java中的字符串都?6位的Unicode。可是用StringBuffer或者char修改字符丌Ӏ从1.5版本之后Q可以用StringBuilder替代StringBufferQStringBuilder速度更快Q但是是U程不安全的?/p>

    String.length()用来获取字符串的长度Q而不是像其他cM使用的length或size()?/p>

    I字W串

    Java中有3U空字符Ԍnull,”“?#8221; “。下面就是如何区别这3中空字符串的Ҏ?/p>

    1 if( s==null) echo( "was null" );
    2 else if( s.length() ==0) echo( "was empty" );
    3 else if( s.trim().length() ==0) echo( "was blank or other whitespace" );
    

    字符串比?/h3>
    1 if( "abc".equals(s) ) echo( "matched" );
    

    ?/p>

    1 if( s.equals( "abc" ) ) echo( "matched" );
    

    当s为nullӞ不会抛出异常Q只会当作它们不相等?除非使用String.intern()对字W串q行合ƈ(interned)Q否则不可以使用==来判断两个字W串是否相等。要使用equals()Ҏ来比较?/p>

    如果一不小心误?=来比较字W串Q编译器也不会发告。不q的是,q个bug直到~译器或者虚拟机昑ּq行规范?interning)Ӟ才会凸显出。规范化(interning)之后Q会获得一个字W串的原始引用。这样其他字W串的副本就可以很快被垃圑֛收器回收。然而,规范?interning)?点不I

  • 要花贚w外的旉在一个HashTable中查扑֎始字W串?/li>
  • 在某些JVM的实CQ有规范化字W串最大长度ؓ64K的限制?/li>
  • 在某些JVM的实CQ规范化后的字符Ԍq不在被引用,也永q不会被垃圾回收器回收?/li>

    如果x较两个字W串的大,׃能用常规的比较操作了,可以使用compareTo()或compareToIgnoreCase()Ҏ替代?/p>

    1 String s ="apple";
    2 String t ="orange";
    3 if( s.compareTo(t) <0)
    4 {
    5    System.out.println( "s < t" );
    6 }
    

    compareTo的返回|

  • 如果s在字W表中排在t之后Q返回正数?/li>
  • 如果s与t位置一Pq回0.
  • 如果s在字W表中排在t之前Q返回负数?/li>

    q个时候可以粗略的把字W串当作数字。返回值就是s-t?/p>

    新手可能会因Z面的几个l果感到惊奇Q?/p>

  • "abc".compareTo( "ABC") returns "abc" > "ABC" compareTo是大写敏感的?/li>
  • "abc ".compareTo ( "abc") returns "abc " > "abc" I格与其他字W一栗?/li>
  • "".compareTo( null) 会抛出:java.lang.NullPointerException 异常?/li>
  • ""与null不同。多数String中的Ҏ可以很好的处?"Q但是很能接受null的?/li>
  • 字符串的比较是通过Unicode数字字符的比较来实现的。不能根据本地语aq行调整?/li>

    当实现自qcLQ默认的Object.equals不会一个个字段q行比较。需要自行实现equals来比较。默认equals只是比较两个引用是否指向同一个对象?/p>

    大小写敏感与大小写不敏感比较

     1 // String comparison, case-sensitive and insensitive.
     2 Stringapple="apple";
     3 Stringorange="orange";
     4 
     5 // case-sensitive compare for equality, faster than order comparison.
     6 booleansame=apple.equals( orange);
     7 
     8 // case-insensitive compare for equality, slower that case-sensitive comparison.
     9 booleansame=apple.equalsIgnoreCase( orange);
    10 
    11 // case-sensitive compare for order.
    12 // +ve if apple>orange, 0 if apple==orange, -ve if apple&lt;orange
    13 intorder=apple.compareTo( orange);
    14 
    15 // case-insensitive compare for order.
    16 // +ve if apple&gt;orange, 0 if apple==orange, -ve if apple&lt;orange
    17 intorder=apple.compareToIgnoreCase( orange);
    18 
    19 // If you are going compare the same strings over and over,
    20 // and you want to compare them in a case-insensitive way, it may pay
    21 // to convert them to lower case, and use the faster case-sensive compare.
    22 StringlcApple=apple.toLowerCase();
    23 StringlcOrange=orange.toLowerCase();
    24 
    25 // effectively a case-insensitive compare for equality,
    26 booleansame=lcApple.equals( lcOrange);
    27 
    28 // effectively a case-insensitive compare for order.
    29 // +ve if apple>orange, 0 if apple==orange, -ve if apple&lt;orange
    30 intorder=lcApple.compareTo( lcOrange);
    

    字符串搜?/h3>

    字符串搜索可使用indexOf和lastIndexOf。他们都可以通过fromOffset改变搜烦开始的位置。返回的l果是相对于字符串开始的位置(0)Q而不是相对于fromOffset的位|。如果搜索时忽略大小写,可先字W串全部转换成大写或写。可以这样实玎ͼ

     1     public static voidmain( String[] args)
     2         {
     3         // use of indexOf
     4         finalStrings1="ABCDEFGABCDEFG";
     5         out.println( s1.indexOf( "CD" ) );
     6         // prints 2, 0-based offset of first CD where found.
     7 
     8         out.println( s1.indexOf( "cd" ) );
     9         // prints -1, means not found, search is case sensitive
    10 
    11         out.println( s1.toLowerCase().indexOf( "cd" ) );
    12         // prints 2,  0-based offset of first cd where found
    13 
    14         out.println( s1.indexOf( "cd".toUpperCase() ) );
    15         // prints 2,  0-based offset of first cd where found
    16 
    17         out.println( s1.indexOf( "CD",4/* start looking here, after the first CD */) );
    18         // prints 9, 0-based offset relative to the original string,
    19         // not relative to the start of the substring
    20 
    21         // use of last indexOf
    22 
    23         out.println( s1.lastIndexOf( "CD" ) );
    24         // prints 9, 0-based offset of where last CD found.
    25 
    26         out.println( s1.lastIndexOf( "cd" ) );
    27         // prints -1, means not found, search is case sensitive
    28 
    29         out.println( s1.toLowerCase().lastIndexOf( "cd" ) );
    30         // prints 9,  0-based offset of where last cd found
    31 
    32         out.println( s1.lastIndexOf( "cd".toUpperCase() ) );
    33         // prints 9,  0-based offset of where last cd found
    34 
    35         out.println( s1.lastIndexOf( "CD",8/* start looking here, prior to last */) );
    36         // prints 2, 0-based offset relative to the original string,
    37         // not relative to the start of the substring
    38 
    39         out.println( "\u00df" );
    40         // prints German esset ligature sz single ss bate-like glyph
    41 
    42         out.println( "\u00df".toUpperCase() );
    43         // prints SS, not SZ, two chars long!
    44         }
    45     }
    

    查找单个字符有很多方法,其中不乏速度比一个一个字W比较是否相{快。理x况下Q编译器_的将indexOfҎ单个字符参数转化为charQ那么可以将x.indexOf(y) >= 0 化ؓx.contains(y)?/p>

    创徏字符?/h3>

    字符串是不可变的Q因此字W串不仅可以被无限期重用Q而且q可在很多场景下׃n。当你将一个字W串变量赋给另外一个字W串变量Ӟ不会再次产生副本。甚臛_调用substring后,赋给了新的变量,也不会创建新的字W串。只有在一下几U情况下才会创徏新的字符Ԍ

  • 字符串拼?/li>
  • 从文件中d字符?/li>
  • 愚蠢的用new String(somethingElse)。一U情况下使用q种方式是恰当的Q参见substring()
  • 使用StringBuffer/StringBuilder的toString或substringҎ
  • toStringҎ

    每种对象都可以调用toStringҎ自w的内容转化成hcdȝ形式。通常Q编写自定义cLQ尽仅仅是ZdegubQ也要单独实现toStringҎ?/p>

    q样来调用:String toShow = myThing.toString();

    默认的Object.toString()很不Q它不会像你期待的那P类中所有字DD出。要辑ֈq种预期Q就要自q码实现。默认的toStringҎ会比较对象的hashCode或者对象的地址?/p>

    toStringҎ有个奇的地斏V在需要{换ؓ字符串时Q好像自动调用toStringq行了{换?/p>

  • 一U情冉|使用QSystem.out.println(and brothers)Q其实它一点儿都不高深Qprintln只是使用众多的重载方法实现的。println有很多重载方法,每个基本数据cd一个。每个基本数据类型的toStringҎ本w{化ؓ字符丌Ӏ但是我们知道基本数据类型中是没有toStringҎ的啊Q确实是q样Q但是别忘记Q有些静态{换方法,比如String.valueOf(double)可以将双精度QҎ转化为字W串。对于Q何String之外的对象,printlnҎ调用的是对象自n重写后的toStringҎQ再结果传l参数只能ؓString的printlnҎ?/li>
  • 当用字W串q接W时(+)QtoString实被调用了。如果将两个对象相加QJava假定你是惛_他们q接Q于是调用各自的toStringҎQ将q接后的字符串返回。在字符串与基本数据cd相加的情况下Q依然奏效。连接符会先把基本数据类型{换ؓ字符Ԍ然后结果连接?/li>

    字符串替?/h3>

    String.replace( char target, char replacement )、String. replace( String target, String replacement ) 两个Ҏ都是替换目标字符串中出现的所有指定的字符或字W串Q但是前者要比后者快很多。所以在替换单个字符Ӟ要用前者,即用单引号。不q的是,后者只有在1.5及其之后的版本中才可以用?/p>

    replaceAll( String regex, String replacement ) Ҏ也是全部替换Q区别在于replaceAllҎ使用正则表达式搜索。欲使用replace( String target, String replacement ) 时千万不能用replaceAll(String regex, String replacement) 。第二个参数不是单的字符ԌString. replaceAll 与Matcher. replaceAll 一栗?代表匚w字符串的引用Q\则是正则表达式中的关键字Q所以需要将\转义为\\\\Q将$转义为\\$?/p>

    replaceFirst( String regex, String replacement ) 也用正则表辑ּ?/p>

    Javadoc中String.replace是以 CharSequence为入参的Q别担心QString实现?CharSequence接口Q所以replace可以在String或StringBuilder中正怋用?/p>

    正则表达?/h3>

    String中包含很多非常好用的正则表达式方法,比如split、matches、replaceAllq有replaceFirst。通常情况下推荐用高效的java.util.regex中的ҎQ方法中的Pattern被提前编译,q且可重用。在不考虑效率的情况下Q就可以使用String中的正则表达式方法了?/p>

    replaceAll和replace都以低效的方式实玎ͼ每次调用都要重新~译regex pattern?/p>

    1 // how replace is implemented.
    2 // It uses regex techniques even though neither parameter is a regex.
    3 publicStringreplace(CharSequencetarget,CharSequencereplacement)
    4 {
    5    returnPattern.compile( target.toString(),Pattern.LITERAL)
    6    .matcher( this).replaceAll( Matcher.quoteReplacement( replacement.toString() ) );
    7 }
    

    所以,如果不止一ơ调用replace或replaceAllӞ最好用单独的正则表达式,~译一ơ即可重用?/p>

    substring

    substring很智能,与其他编E语a的深拯不同Q它只是创徏一个指向原始不可变字符串的引用。比如根据substring参数讄char的偏Ud|与count属性值后Q返回一个指向它的引用,而不是全部拷贝。这样就l调试增M困惑Q因为每ơ看到的都是整个字符串而不是截取后的子丌Ӏ这样做有一个致命的~点Q就是子串一直保持着整个原始字符串的引用Q这样即使原始字W串已经没用了,也不能被垃圾回收器回收?事实上String对象的引用可以被回收Q但是RAM中的char没法被回?

    所以查扑֭W串Ӟ使用indexOf(lookFor, offset)要好于先使用substring创徏子串再用indexOf(lookFor)?/p>

    如果切的知晓小子串会指向RAM中原始大字符串的charQ其不能被回收Q这个时候可以用littleString = new String(littleString)来创Z个与原始字符串无关的新字W串来避免这U情늚发生?/p>

    如果你是通过src.zip来学习String.substring()Q那么这U?#8221;陷阱”很难被发现。因为它是用qString的一个非公有构造方法String (int offset, int count, char value) 来调整value的偏Ud和count值来实现?/p>

    原文链接Q?a >http://mindprod.com/jgloss/string.html
                     http://mindprod.com/jgloss/substring.html



  • 齐纳多 2012-02-27 14:49 发表评论
    ]]>
    Jvm查看工具http://www.aygfsteel.com/xiaofei-suman/articles/370828.html齐纳多齐纳多Mon, 27 Feb 2012 03:48:00 GMThttp://www.aygfsteel.com/xiaofei-suman/articles/370828.htmlhttp://www.aygfsteel.com/xiaofei-suman/comments/370828.htmlhttp://www.aygfsteel.com/xiaofei-suman/articles/370828.html#Feedback0http://www.aygfsteel.com/xiaofei-suman/comments/commentRss/370828.htmlhttp://www.aygfsteel.com/xiaofei-suman/services/trackbacks/370828.html1.jps cM于ps 可以查看java的进E?br />2.jstat jvm垃圾攉内存使用情况

    S0:Survior1区内存占?br />S1:Survior2区内存占?br />E:Eden(新生?Eden)
    O:Old(老年?
    P:持久?br />YGC:新生代gcơ数(minor gc)
    YGCTQgc旉
    FGCQfull  gc ơ数
    FGCT:full  gc旉
    GCT: 总gc旉 
    3.gc日志输出
      -XX:+PrintGC                   gc概要信息
      -XX:+PrintGCDetails          gc详细信息
      -XX:+PrintGCTimeStamps    GC停顿耗时
      -XX:+PrintGCApplicationStopedTime  用户q程停顿旉(stop the world)
      再加?Xloggc:文g路径   gc信息会输出到指定的文g?br />4.jconsole可以q程或者本地监控jvm内存信息Q线E信? cd载信?MBean信息

     5.jmap
     6.jhat
     7.jvisualVm
     8.eclipse memory analysis


    齐纳多 2012-02-27 11:48 发表评论
    ]]>
    发扑克牌的简?java)实现http://www.aygfsteel.com/xiaofei-suman/articles/370480.html齐纳多齐纳多Wed, 22 Feb 2012 01:28:00 GMThttp://www.aygfsteel.com/xiaofei-suman/articles/370480.htmlhttp://www.aygfsteel.com/xiaofei-suman/comments/370480.htmlhttp://www.aygfsteel.com/xiaofei-suman/articles/370480.html#Feedback0http://www.aygfsteel.com/xiaofei-suman/comments/commentRss/370480.htmlhttp://www.aygfsteel.com/xiaofei-suman/services/trackbacks/370480.html
    package cn.com.pbqi.corejava;

    import java.util.ArrayList;
    import java.util.Iterator;
    import java.util.List;
    import java.util.Map;
    import java.util.Random;
    import java.util.TreeMap;

    public class CardGame {
        
        
    private int pNum;
        
    private List<String> cardList = new ArrayList<String>(54);
        
    private Map<String,List<String>> map = new TreeMap<String,List<String>>();
        
        
    /**
         * 打牌的h?最?个h,最?个h
         * 
    @param pNum
         
    */

        
    public CardGame(int pNum) {
            
    if(pNum < 2 || pNum > 4{
                
    throw new IllegalArgumentException("CardPlayer must between 2 and 4, CardPlayer=" + pNum);
            }

            
    this.pNum = pNum;
            
    for(int i = 0; i <pNum; i++{
                map.put(i
    +"-"new ArrayList<String>());
            }

            
            
    this.initCards();
            
            
    this.distribute();
            
            
    this.display();
        }

        
        
    /**
         * 初始化一副扑?br />     
    */

        
    public List<String>  initCards() {
            String[] type 
    = {"r","b","s","m"};
            String[] cards 
    = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
            String[] kings 
    = {"大王",""};
            
            
    for(int i = 0; i < type.length; i++{
                
    for(int j = 0; j < cards.length;j++{
                    cardList.add(cards[j]
    +type[i]);
                }

            }

            
    for(int k = 0; k < kings.length; k++){
                cardList.add(kings[k]);
            }

            
    return cardList;
        }

        
    /**
         * 发牌
         
    */

        
    public void distribute() {
            Random r 
    = new Random();
            
    int len = cardList.size();
            
    int bakLen = len;
            
    for(int i = 0; i < len; i++{
                
    int rNum = r.nextInt(bakLen);
                String card 
    = cardList.get(rNum);
                
    int left = i % pNum;
                map.get(left
    +"-").add(card);
                cardList.remove(rNum);
                bakLen
    --;
            }

        }

        
        
    public void display() {
            System.out.println(
    "======r:U桃,b:黑桃,s:方块,m:c===========");
            
    for(Iterator<String> iter = map.keySet().iterator(); iter.hasNext();) {
                String key 
    = iter.next();
                List
    <String> list = map.get(key);
                System.out.print(key
    + " 的牌?==");
                
    for(int i = 0; i < list.size();i++{
                    System.out.print(list.get(i));
                    
    if(i != list.size() -1{
                        System.out.print(
    ",");
                    }

                }

                System.out.println(
    "");
            }

        }

        
        
    public static void main(String[] args) {
            CardGame cg 
    = new CardGame(4);

        }


    }



    齐纳多 2012-02-22 09:28 发表评论
    ]]>
    求一个字W串是否是回文数http://www.aygfsteel.com/xiaofei-suman/articles/246550.html齐纳多齐纳多Tue, 16 Dec 2008 01:40:00 GMThttp://www.aygfsteel.com/xiaofei-suman/articles/246550.htmlhttp://www.aygfsteel.com/xiaofei-suman/comments/246550.htmlhttp://www.aygfsteel.com/xiaofei-suman/articles/246550.html#Feedback2http://www.aygfsteel.com/xiaofei-suman/comments/commentRss/246550.htmlhttp://www.aygfsteel.com/xiaofei-suman/services/trackbacks/246550.html 

    /**
     * 判断一个字W串是否是回文数
     *
     * 
    @author Qinaldo
     *
     
    */

    public class PalindromeNum {

        
    public static void main(String[] args) {
            
            
    while(true{
                
                System.out.println(
    "误入一个字W串Q?/span>");
                Scanner scan 
    = new Scanner(System.in);
                String str 
    = scan.next();
                
                
    int len = str.length();
                
    int i;
                
                
    if("bye".equals(str)) {
                    
    break;
                }

                
                
    for(i=0; i<len/2; i++{
                    
    if(str.charAt(i) != (str.charAt(len-i-1))) {
                        
    break;
                    }
     
                }

                
                
    if(i >= len/2{
                    System.out.println(str 
    + ",是回文数Q?/span>");
                }
     else {
                    System.out.println(str 
    + ",不是回文敎ͼ");
                }

            }

        }

    }


    齐纳多 2008-12-16 09:40 发表评论
    ]]>
    java?排列l合 33? 的另cd?/title><link>http://www.aygfsteel.com/xiaofei-suman/articles/244386.html</link><dc:creator>齐纳多</dc:creator><author>齐纳多</author><pubDate>Thu, 04 Dec 2008 07:32:00 GMT</pubDate><guid>http://www.aygfsteel.com/xiaofei-suman/articles/244386.html</guid><wfw:comment>http://www.aygfsteel.com/xiaofei-suman/comments/244386.html</wfw:comment><comments>http://www.aygfsteel.com/xiaofei-suman/articles/244386.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/xiaofei-suman/comments/commentRss/244386.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/xiaofei-suman/services/trackbacks/244386.html</trackback:ping><description><![CDATA[<p>package com.qpb.ant;</p> <p>import java.util.ArrayList;<br /> import java.util.List;<br /> import java.util.Random;</p> <p>public class TestRandom {<br />  <br />  public final static int TOTAL = 33;<br />  public final static int NUMBER = 7;<br />  <br />  public static void main(String[] args) {<br />       List<String> list = new ArrayList<String>();<br />       StringBuffer sb = new StringBuffer();<br />       Random r = new Random();<br />   <br />       for(int i = 0; i < TOTAL; i++) {<br />            list.add(i + 1 + "");<br />       }<br />   <br />       for(int j = 0; j < NUMBER; j++) {<br />            int size = list.size();<br />            String s = list.get(r.nextInt(size));<br />            sb.append(s);<br />            if(j != NUMBER -1) {<br />                 sb.append(",");<br />            }<br />            list.remove(s);<br />       }<br />           System.out.println(sb.toString());<br />      }</p> <p>}</p> <img src ="http://www.aygfsteel.com/xiaofei-suman/aggbug/244386.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/xiaofei-suman/" target="_blank">齐纳多</a> 2008-12-04 15:32 <a href="http://www.aygfsteel.com/xiaofei-suman/articles/244386.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss> <footer> <div class="friendship-link"> <a href="http://www.aygfsteel.com/" title="狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频">狠狠久久亚洲欧美专区_中文字幕亚洲综合久久202_国产精品亚洲第五区在线_日本免费网站视频</a> </div> </footer> վ֩ģ壺 <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ǿ</a>| <a href="http://" target="_blank">°Ͷ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ͨ</a>| <a href="http://" target="_blank">ʦ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">˳</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">Ӧñر</a>| <a href="http://" target="_blank">ʲ</a>| <a href="http://" target="_blank">ɼ</a>| <a href="http://" target="_blank">̷</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ʯ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">º</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">⴨</a>| <a href="http://" target="_blank">ɽ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank">ֹ</a>| <a href="http://" target="_blank">ɳ</a>| <a href="http://" target="_blank">̨</a>| <a href="http://" target="_blank">Ϫ</a>| <a href="http://" target="_blank">ʡ</a>| <a href="http://" target="_blank"></a>| <a href="http://" target="_blank"></a>| <script> (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })(); </script> </body>