zoukankan      html  css  js  c++  java
  • 字符串和字符串池

    一、字符串

    1.字符串的创建

    (1)直接创建:String s="Hello";

    (2)new创建:String s=new String("Hello")

    要注意空字符串和null是不相同的

    public static void main(String[] args)
    {
           String s1="";
           String s3=new String();
           String s2=new String("");
    String s4=null; System.out.println(s1.equals(s2)); //s1、s2相等都是空字符串 System.out.println(s2.equals(s3)); //s2、s3相等 System.out.println(s3.equals(s4)); //s1、s2、s3与s4不相等! }

    除了new ("Hello")中的类型之外,还能有如下方式:

             String s1="Hello1";
             String s2=new String(s1);         
             char []c={'H','e','l','l','o','2'};
             String s3=new String(c);                   //但不能String s3=new String({'H','e','l','l','o'});
             byte []b={'H','e','l','l','o','3'};
             String s4=new String(b);
             StringBuffer sb=new StringBuffer(new String("Hell04"));
             String s5=new String(sb);
             StringBuilder sbu=new StringBuilder(new StringBuffer("Hello5"));
             String s6=new String(sbu);
             System.out.println(s1+s2+s3+s4+s5+s6);

    可以看出还可以以byte[]、char[]、String、StringBuffer、StringBuilder均可作为String构造函数的参数。

    (3)vauleOf()创建

    普通数据类型 String s1=String.vauleOf(true);或者是int bl=54;String s1=String.vauleOf(bl);直接将其转换为String.

    引用数据类型通过调用成员方法toString()来将对象转换为字符串。对于System.out.println(obj);若obj==null则会返回null。

    Object o=null;
    System.out.println(o);   //输出null字符串
    System.out.println(o.toString()); //运行抛出异常java.lang.NullPointerException

    否则等同于语句System.out.println(obj.toString());

    //toString()方法

    再来探讨一下toString()方法,如果调用它的是一个字符串对象包括String、StringBuffer、StringBuilder则会返回当前字符串,如果是基础数据的引用,例如Integer、Character、Boolean则会返回对应的int、char、boolean等对应的数据字符串。如果是其他类对象,重写toStirng()方法就不说了,但是未重写方法就会输出"包名.类名@哈希码十六进制"(此处包含数组)。

    class A
    {
    }
    public class Strings {
    
    	public static void main(String[] args) {
               A a=new A();
               A a0=new A();
               System.out.println(a.toString());
               System.out.println(a0);
    	}
    
    }
    

    输出:

    arraytest.A@70dea4e
    arraytest.A@5c647e05

    //System.out.println()方法

    而我们常用的System.out.println()方法其实就是将参数转化为字符串,而主要方法就是(3)中的构造方法,若是基本类型,就使用vauleOf(),若是非null引用类型就调用toString(),若是null类型数据就返回null(null不能直接作为参数,只能是某对象指向null,然后打印此对象的形式);

    class A
    {
    }
    class B
    {
        public String toString()
        {
            return "BB";
        }
    }      
               char []c={'H','e','l','l','o','2'};    //数组
               StringBuffer sb=new StringBuffer(new String("Hell04"));    //字符串对象
               Integer i=9;                         //基本类型的包装类
               boolean bl=false;                    //基本数据类型
               Object o=null;                      //null
               A a=new A();                        //非null无重写
               B b=new B();                        //非null有重写
               System.out.println(c);               //打印Hello2
               System.out.println(c.toString());    //打印[C@70dea4e,地址
               System.out.println(i);                //9,调用toString()
               System.out.println(bl);                //false,调用valueOf()
               System.out.println(o);                   //null,无法使用toString()
               System.out.println(a);                   //地址
               System.out.println(b.toString());        //BB

        值得一提的就是字符串数组,在直接打印时会输出字符串内容,但在调用toString()方法时会打印地址[C@70dea4e,而其余类型数组都会打印地址[就是包名,C就是类名?

    (4)直接+

    两个直接字符串相加。String s1="123"+"456"

    字符串和其他相加时会采用和println相同的策略

               byte []b={'H','e','l','l','o','3'};        
    Object o=null; String s1="123"+new Integer(456); String s2="123"+o; String s3="123"+false; String s4="123"+b; System.out.println(s1); //123456,调用toString() System.out.println(s2); //123null System.out.println(s3); //123false,调用valueOf() System.out.println(s4); //123[B@70dea4e,调用toString()

    仍然来重点看一下字符数组,在+连接符下,会直接调用toString()从而返回其地址,不会访问其内容,编程与其他类型数组一样。

    2.字符串的操作

     (1)public String concat(String str)进行拼接操作,若str是空字符串,则还返回原来的引用。

    public static void main(String []args)
    {
        String s1="123";
        String s2="456";
        System.out.println(s1);
        System.out.println(s1.hashCode());
        s1=s1.concat(s2);
        System.out.println(s1);
        System.out.println(s1.hashCode());
    }

    输出:123
    48690
    123456
    1450575459      可以看出若str不为空就会返回一个新的引用。

    (2)String replace(char oldChar,char newChar)将所有oldChar字符替换为newChar,String toLowerCase()、String toUpperCase()转换大小写,String trim()去空白字符,对于这些方法来说若不改变原有字符串的,例如replace()不含oldChar,转换成小写的不含小写字符串,或不含空白字符等就不会修改原引用。String substring(int beginIndex)和String substring(int beginIndex,int endIndex)是截取从第beginIndex+1到结束的子字符串和从第beginIndex+1到nedIndex的子字符串。

    (3)format()方法,先不赘述

    (4)int length()返回长度,boolean isEmpty()返回是否为空,char charAt(int index)返回第index+1的字符;

    int indexOf(int ch)查找ch第一次出现的位置,若不含此字符,返回-1,不要误以为写错了,确实是参数为int类型,这里指的是Unicode码。int indexOf(int ch,int fromIndex)功能相同但需要从大于等于fromIndex的下标(注意和第几个区分)开始查找。int indexOf(String str)前提是str是子字符串,返回第一个字符的下标,int indexOf(String str,int fromIndex)类似。

    int lastIndexOf(int ch)、int lastIndexOf(String str)返回最后一个符合条件的字符下标、最后一个符合的字符串的第一个下标,int lastIndexOf(int ch,int fromIndex)和int lastIndexOf(String str,int fromIndex)返回小于等于fromIndex的最后一个下标或字符串的第一个下标。(语文不好(lll¬ω¬),还是上例子吧)

    	String s="abcabcdabcde";
    	System.out.println(s.indexOf('b'));       //1
    	System.out.println(s.indexOf('b',1));     //1,Ifirst('b')=1>=1,返回1
    System.out.println(s.indexOf('b',2)); //4,Ifirst('b')=1<1,寻早下一个b,Ifirst('b')=4>=1,返回4
    System.out.println(s.indexOf("abc",0)); //0 System.out.println(s.indexOf("abc",1)); //3,判断abc字串首字符a字符下标和1的大小,若Ifirst('a')>=1,返回Ifirst('a'),否则找到下一个abc字符串再判断直到符合 System.out.println(s.indexOf("ab",-1)); //0,第二个参数小于0与等于0等价与没有第二个参数等价 System.out.println(s.lastIndexOf("ab")); //7 System.out.println(s.lastIndexOf('c',8)); //5,若Ilast('c')<=8,则返回Ilast('c'),可以看出9>8不符合,寻找下一个5符合 System.out.println(s.lastIndexOf("abc",7)); //7,先倒着找出“abc”字符串,然后判断Ilast('a')=7<=7,所有返回7 System.out.println(s.lastIndexOf("abc",29)); //7,任何大于字符串长度的第二参数与没有第二参数等价

      其中的Ifirst('a')表示正向查找a字符符合条件的下标,Ilast自然是指逆序查找下标。

    (5)字符串的比较int compareTo(String another) (参数不能是null???),返回值第一个不相同字符unicode码差值,若两一个字符串是另一字符串字串,返回字符串长度差值,若两串相同则返回0.此外还有int compareToIgnoreCase(String another)比较方法与其类似,但忽略掉大小写。

    判断两字符串相等不能用等号==(后面长篇幅介绍)要用boolean equals(Object anObj)你没看错正是Object类型的参数,但你用其他对象做参数他返回false,即使是StringBuffer对象也一样,null可以作为参数但会永远返回false,因为调用此成员方法永远不会是null。boolean equalsIgnoreCase(String another)忽略大小写。

    (6)将字符串转为基本类型parseXxx.例如转为double型 public static double parseDouble(String s) throws NumberFormatException 可以看出要想转换为double你的字符串必须要符合相应格式。但有一个例外parseBoolean除非字符串是“true”或“TRue”等返回true,其余均返回false,也就是说可以不符合格式。注:char类型可以直接由charAt方法获得。

    转换为byte数组public byte[] getBytes()、转换为字节数组public char[] toCharAyyay()。

    二、字符串池(重点)

    (1)直接赋值:String s="123456";先查找字符串池中是否有该字符串,若没有则创建一个对象,并返回。若有此字符串直接返回。【创建1个对象】

    (2)new创建:String s=new Stirng("123456");先查找字符串池中是否有该字符串,若有直接在堆中new一个对象并返回,没有就在字符串中先创建一个,然后再在堆中new一个返回。【创建2个对象】

    (3)+连接两个字符串:String s="123"+"456";分别判断字符串“123”和"456"在字符串池中是否存在,若不存在就创建一个。然后判断连接后的字符"123456"在字符串池中是否存在,若不存在就创建。【3个对象】

    (4)+连接对象和对象或连接对象和字符串:String s1="123";String s2=s1+"456"; String s3="456";String s4=s1+s3;具体情况有待证实,应该是先创建"123"对象(包括判断),然后创建“456”对象,…………

    (5)new字符串对象或+连接:String s1="123456";String s2=new(s1); String s3="123";String s4=new String(s3+"456"); 

    (6)intern()方法:若字符串池中有字符串直接返回,否则创建一个对象。

        String s="123456";                  
        String s1="123456";
        String s2=new String("123456");
        String s3="123"+"456";
        String s4="123";
        String s5=s4+"456";
        String s6="456";
        String s7=s4+s6;
        String s8=new String(s1);
        String s9=new String(s4+"456");
        System.out.println(s1==s);   //true
        System.out.println(s1==s2);  //false
        System.out.println(s1==s3);  //true
        System.out.println(s1==s5);  //false
        System.out.println(s1==s7);  //false
        System.out.println(s1==s8);  //false
        System.out.println(s1==s9);  //false
        System.out.println(s==s2.intern()); //true
        System.out.println(s2==s2.intern());//false
        System.out.println(s2.intern()==s5.intern());//true

    可以总结一下,赋值字符串直接量几个字符串直接量的连接相同字符串的intern()返回值都是相等的,其余方法都是互不相等且与上述几种不相等。

  • 相关阅读:
    Java中的线程Thread方法之---interrupt() 分类: Android Java 2014-02-26 08:51 3189人阅读 评论(2) 收藏
    Java中的对象Object方法之---wait()和notifiy() 分类: Java Android 2014-02-26 08:50 1599人阅读 评论(0) 收藏
    Java中的线程Thread方法之---suspend()和resume() 分类: Java 2014-02-25 14:37 1650人阅读 评论(0) 收藏
    Java中的线程Thread方法之---join() 分类: Android Java 2014-02-25 13:38 1393人阅读 评论(0) 收藏
    Java中的线程Thread方法之---stop() 分类: Java 2014-02-25 09:59 3075人阅读 评论(1) 收藏
    抓包工具Fidder详解(主要来抓取Android中app的请求) 分类: Android 2014-02-24 09:32 10064人阅读 评论(5) 收藏
    XML的解析 分类: JavaWeb Java Android 2014-02-17 18:22 1764人阅读 评论(3) 收藏
    XML文件定义约束 分类: JavaWeb 2014-02-17 17:49 1127人阅读 评论(0) 收藏
    Android中的广播Broadcast详解 分类: Android 2014-02-13 10:59 8414人阅读 评论(5) 收藏
    GitHub错误处理:fatal:could not read Username for 'https://github.com': No such file or directory 分类: Java 2014-02-11 19:39 2346人阅读 评论(0) 收藏
  • 原文地址:https://www.cnblogs.com/lbrs/p/9017360.html
Copyright © 2011-2022 走看看