Java中字符串(String)总结

先说说JDK API:

JDK中包含大量的API类库,所谓API(Application Programming Interface,应用程序编程接口,这些功能以类的形式封装)。

JDK API包含的类库功能强大,经常使用的有:字符串操作,集合操作,文件操作,输入输出操作,网络操作,多线程等等。

JDK包结构

围栏便于使用和维护,JDK类库按照包结构划分,不同功能的类划分在不同的包中;经常使用的包如下所示:

java.lang:Java程序的基础类,如字符串,多线程等,该包中的类使用是频率非常高,不需要import,可以直接使用

java.util:常用工具类,如集合,随机数产生器,日历,始终等等

java.io:文件操作,输入输出操作

java.net:网络操作

java.math:数学运算相关操作

java.security:安全相关操作

java.sql:数据库访问

java.text:处理文字,日期,数字,信息的格式

String基本概念

java.lang.String使用了final修饰,不能被继承;

字符串底层封装了字符数组及针对字符数组的操作算法;

字符串一旦创建,对象永远无法改变,但字符串引用可以重新赋值;

Java字符串在内存中采用Unicode编码方式,任何一个字符对应两个字节的定长编码;

String常量池:

Java为了提高性能,静态字符串(字面量/常量/常量连接的结果)在常量池中创建,并尽量使用同一个对象,重用静态字符串;

对于重复出现的字符串常量,JVM会首先在常量池中查找,如果存在即返回该对象。

String str1="Hello"; //创建对象
//不会创建新的对象,而是使用常量池中已有的对象 String str2="Hello"; System.out.println(str1==str2); //输出true //使用new关键字会创建新的String对象 String str3=new String("Hello"); System.out.println(str1==str3);//输出false

内存编码及长度

String在内存中采用Unicode编码,每个字符占用两个字节;任何一个字符(无论中文还是英文)都算一个字符长度,占用两个字节。

使用indexOf实现检索:

indexOf方法用于实现在字符串中检索另一个字符串

String提供几个indexOf方法

int indexOf(String str):在字符串中检索str,返回其第一次出现的位置,如果找不到则返回-1

int indexOf(String str,int formIndex):从字符串formIndex位置开始检索

 

String还定义有lastIndexOf方法:

int lastIndexOf(String str,int form):str在字符串中多次出现时,将返回最后一个出现的位置

package stringDemo;

public class demo1 {
    public static void main(String[] args) {
        String str="I can because i think i can";
        int index=str.indexOf("can");
        System.out.println(index);  //2
        
        index=str.lastIndexOf("can");
        System.out.println(index); //24
        
        index=str.lastIndexOf("can",6);
        System.out.println(index); //24
        
        index=str.indexOf("my"); //-1
        
    }

}

使用substring获取字符串

substring方法用于返回一个字符串的子字符串

substring常量重载方法定义如下:

String substring(int beginIndex,int endIndex):返回字符串中从下标beginIndex(包括)开始到endIndex(不包括)结束的子字符串

String subString(int beginIndex):返回字符串中从下标beginIndex(包含)开始到字符串结尾的子字符串

package stringDemo;

public class demo1 {
    public static void main(String[] args) {
        
        String str="http://www.oracle.com";
        String substr=str.substring(11,17);//oracle
        System.out.println(substr);
        substr=str.substring(7);
        System.out.println(substr);//www.oracle.com
    }
}

使用trim()方法去掉一个字符串的前导和后继空字符串

package stringDemo;

public class demo1 {
    public static void main(String[] args) {
        String userName=" good boy";
        System.out.println(userName);
        userName=userName.trim();
        System.out.println(userName);    
    }
}

String中定义的charAt()方法:

char charAt(int index):方法charAt()用于返回字符串指定位置的字符,参数index表示指定的位置

package stringDemo;

public class demo2 {

    public static void main(String[] args) {
        String name="whatisjava";
        for(int i=0;i<name.length();i++){
            char c=name.charAt(i);
            System.out.print(c+"");//whatisjava
        }
    }
}

startsWith和endsWith方法:检测一个字符串是否以指定字符串开头或结尾

package stringDemo;

public class demo2 {

    public static void main(String[] args) {
        String name="whatisjava";
        System.out.println(name.endsWith("java"));
        System.out.println(name.startsWith("w"));
    }
}

大小写变换toUpperCase和toLowerCase方法:转换字符串中英文字母的大小写形式:

package stringDemo;

public class demo2 {

    public static void main(String[] args) {
        String name="我喜欢Java";
        name=name.toUpperCase();
        System.out.println(name);
        name=name.toLowerCase();
        System.out.println(name);
    }
}

valueOf方法:将其他方法转换为字符串类型

package stringDemo;

public class demo2 {

    public static void main(String[] args) {
        double pi=3.1415926;
        int value=123;
        boolean flag=true;
        char[] charArr={'a','b','c'};

        String str=String.valueOf(pi);
        System.out.println(str);

        str=String.valueOf(value);
        System.out.println(str);

        str=String.valueOf(flag);
        System.out.println(str);

        str=String.valueOf(charArr);
        System.out.println(str);
    }
}

分割字符串:

利用字符串类的split方法进行分割

 

package stringDemo;

public class demo1 {
    public static void main(String[] args) {
        String userName=" hello,good,boy";
        System.out.println(userName);
        String [] str=userName.split(",");
        for(String s:str)
        System.out.println(s);
    }
}

利用StringTokenizer来进行字符串分割

  /** *//**利用StringTokenizer来进行字符串分割
     * @param str  待分割的字符串
     * @param sdelimiter  分割符
     * @return
     */
    public String[] useStringTokenizer(String str,String sdelimiter)...{
        StringTokenizer token=new StringTokenizer(str,sdelimiter);
        String[] array=new String[token.countTokens()];
        int i=0;
        while(token.hasMoreTokens())...{
            array[i]=token.nextToken();
            i++;
        }
        return array;
    }

字符串数组排序

/** *//**对字符串数组进行排序
     * @param str 原始字符串数组
     * @param flag flag=0:顺序排序  flag=1:倒序排序
     * @return 排序后的字符串数组
     */
    public String[] sort(String[] str,int flag)...{
        if(str==null||str.length==0)
            throw new IllegalArgumentException();
        String temp=str[0];
        //顺序排列 ,即从小到大
        if(flag==0)...{
            for(int i=0;i<str.length-1;i++)...{
                for(int j=i+1;j<str.length;j++)...{
                    if(str[i].compareTo(str[j])>0)...{
                        temp=str[i];
                        str[i]=str[j];
                        str[j]=temp;
                    }
                }
            }
        }
        else if(flag==1)...{//倒序排列
            for(int i=0;i<str.length-1;i++)...{
                for(int j=i+1;j<str.length;j++)...{
                    if(str[i].compareTo(str[j])<0)...{
                        temp=str[i];
                        str[i]=str[j];
                        str[j]=temp;
                    }
                }
            }
        }
        return str;
    }

使用Hashtable对字符串进行碰撞

利用hashtable对字符串进行过滤,两个字符数组之间的比较,对字符串数组进行过滤

1.在一些字符串数组中,常会有重复的记录,比如手机号码,我们可以通过Hashtable来对其进行过滤

public String[] checkArray(String[] str)...{
        Hashtable<String, String> hash=new Hashtable<String, String>();

        for(int i=0;i<str.length;i++)...{
            if(!hash.containsKey(str[i]))
                hash.put(str[i], str[i]);
        }

        Enumeration enumeration=hash.keys();
        String[] str_new=new String[hash.size()];
        int i=0;

        while(enumeration.hasMoreElements())...{
            str_new[i]=enumeration.nextElement().toString();
            i++;
        }
        return str_new;
    }

2.A,B均为字符串数组,找出在A中存在,而在B中不存在的字符串

 public String[] compareArray(String[] A,String[] B){
        Hashtable<String, String> hash=newHashtable<String, String>();
        Hashtable<String, String>hash_new=new Hashtable<String, String>();

        for(int i=0;i<B.length;i++)
            hash.put(B[i], B[i]);

        for(int i=0;i<A.length;i++){
           if(!hash.containsKey(A[i]))
               hash_new.put(A[i], A[i]);
        }

        String[] C=new String[hash_new.size()];
        int i=0;
        Enumeration enumeration=hash_new.keys();

        while(enumeration.hasMoreElements()){
           C[i]=enumeration.nextElement().toString();
            i++;
        }
        return C;
    }

3.将一个字符串数组中某一个特定的字符串过滤掉

/** *//**检验一个字符串数组,若包含某一特定的字符串,则将该字符串从数组中删
除,返回剩余的字符串数组
     * @param str_array  字符串数组
     * @param str_remove 待删除的字符串
     * @return 过滤后的字符串
     */
    public String[] removeStrFromArray(String[] str_array,String
str_remove)...{
        Hashtable<String, String> hash=new Hashtable<String, String>();
        for(int i=0;i<str_array.length;i++)...{
            if(!str_array[i].equals(str_remove))
                hash.put(str_array[i], str_array[i]);
        }
        //生成一个新的数组
        String[] str_new=new String[hash.size()];
        int i=0;
        Enumeration enumeration=hash.keys();
        while(enumeration.hasMoreElements())...{
            str_new[i]=enumeration.nextElement().toString();
            i++;
        }
        return str_new;
    }

 

StringBuild

StringBuilder封装可变字符串,对象创建后可以通过调用方法改变其封装的字符序列。

StringBuilder有如下常用构造方法:

public StringBuilder()

public StringBuilder(String str )

 

StringBuilder常用方法:

StringBuilder append(String str):追加字符串.

package stringDemo;

public class demo3 {
    public static void main(String[] args) {
        StringBuilder stb=new StringBuilder("hello");
        System.out.println(stb);
        stb=stb.append("word");
        System.out.println(stb);
    }
}

 

StringBuilder insert(int desOffset,String s):插入字符串

package stringDemo;

public class demo3 {
    public static void main(String[] args) {
        StringBuilder stb=new StringBuilder("hello");
        System.out.println(stb);
        stb=stb.insert(3, "word");
        System.out.println(stb);
    }
}

 

StringBuilder delete(int start,int end):删除字符串

package stringDemo;
public class demo3 {
    public static void main(String[] args) {
        StringBuilder stb=new StringBuilder("hello");
        stb=stb.delete(2, 5);
        System.out.println(stb);
    }
}

 

StringBuilder replace(int start,int end,String s):替换字符串

package stringDemo;
public class demo3 {
    public static void main(String[] args) {
        StringBuilder stb=new StringBuilder("hello");    
        stb=stb.delete(2, 5);
        System.out.println(stb);
    }
}

 

StringBuilder reverse():字符串反转

package stringDemo;

public class demo3 {
    public static void main(String[] args) {
        StringBuilder stb=new StringBuilder("hello");
                System.out.println(stb);//hello
        stb=stb.reverse();
        System.out.println(stb);//olleh
    }
}

注意:

StringBuilder的很多方法的返回值均为StringBuilder类型,这些方法的返回语句为:return this.

由于改变封装的字符序列后又返回了该对象的引用,因此可以按照简洁的方式书写代码:

buf.append("ibm").insert(3,"oracle").repalce(9,13,"java");

 

StringBuilder是可变字符串,字符串的内容计算建议使用StringBuillder实现,这样性能会好一些。

Java的字符串连接过程是利用StringBuilder实现的。

 

StringBuffer常用方法

(StringBuffer和StringBuilder在使用上几乎一样)

StringBuffer s = new StringBuffer();

这样初始化出的StringBuffer对象是一个空的对象,

 StringBuffer sb1=new StringBuffer(512);
分配了长度512字节的字符缓冲区。 

StringBuffer sb2=new StringBuffer(“how are you?”)

创建带有内容的StringBuffer对象,在字符缓冲区中存放字符串“how are you?”

 

 a、append方法
public StringBuffer append(boolean b)
该方法的作用是追加内容到当前StringBuffer对象的末尾,类似于字符串的连接,调用该方法以后,StringBuffer对象的内容也发生改 变,例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.append(true);
则对象sb的值将变成”abctrue”

使用该方法进行字符串的连接,将比String更加节约内容,经常应用于数据库SQL语句的连接。

 

 b、deleteCharAt方法
public StringBuffer deleteCharAt(int index)
该方法的作用是删除指定位置的字符,然后将剩余的内容形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“KMing”);
sb. deleteCharAt(1);
该代码的作用删除字符串对象sb中索引值为1的字符,也就是删除第二个字符,剩余的内容组成一个新的字符串。所以对象sb的值变 为”King”。
还存在一个功能类似的delete方法:
public StringBuffer delete(int start,int end)
该方法的作用是删除指定区间以内的所有字符,包含start,不包含end索引值的区间。例如:
StringBuffer sb = new StringBuffer(“TestString”);
sb. delete (1,4);
该代码的作用是删除索引值1(包括)到索引值4(不包括)之间的所有字符,剩余的字符形成新的字符串。则对象sb的值是”TString”。 

 

 c、insert方法
public StringBuffer insert(int offset, boolean b),
该方法的作用是在StringBuffer对象中插入内容,然后形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“TestString”);
sb.insert(4,false);
该示例代码的作用是在对象sb的索引值4的位置插入false值,形成新的字符串,则执行以后对象sb的值是”TestfalseString”。 

 

 d、reverse方法
public StringBuffer reverse()
该方法的作用是将StringBuffer对象中的内容反转,然后形成新的字符串。例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.reverse();
经过反转以后,对象sb中的内容将变为”cba”。 

 

 e、setCharAt方法
public void setCharAt(int index, char ch)该方法的作用是修改对象中索引值为index位置的字符为新的字符ch。例如:
StringBuffer sb = new StringBuffer(“abc”);
sb.setCharAt(1,’D’);
则对象sb的值将变成”aDc”。 

 

 f、trimToSize方法
public void trimToSize()
该方法的作用是将StringBuffer对象的中存储空间缩小到和字符串长度一样的长度,减少空间的浪费,和String的trim()是一样的作用,不在举例。

 

 g、length方法
该方法的作用是获取字符串长度 ,不用再说了吧。

 

 h、setlength方法
该方法的作用是设置字符串缓冲区大小。
StringBuffer sb=new StringBuffer();
sb.setlength(100);
如果用小于当前字符串长度的值调用setlength()方法,则新长度后面的字符将丢失。 

 

 i、sb.capacity方法
该方法的作用是获取字符串的容量。
StringBuffer sb=new StringBuffer(“string”);
int i=sb.capacity(); 

 

 j、ensureCapacity方法
该方法的作用是重新设置字符串容量的大小。
StringBuffer sb=new StringBuffer();
sb.ensureCapacity(32); //预先设置sb的容量为32 

 

 k、getChars方法
该方法的作用是将字符串的子字符串复制给数组。
getChars(int start,int end,char chars[],int charStart); 

StringBuffer sb = new StringBuffer("I love You");
int begin = 0;
int end = 5;
//注意ch字符数组的长度一定要大于等于begin到end之间字符的长度
//小于的话会报ArrayIndexOutOfBoundsException
//如果大于的话,大于的字符会以空格补齐
char[] ch  = new char[end-begin];
sb.getChars(begin, end, ch, 0);
System.out.println(ch);

结果:I lov

 

String、StringBuffer、StringBuilder区别

StringBuffer、StringBuilder和String一样,也用来代表字符串。String类是不可变类,任何对String的改变都 会引发新的String对象的生成;StringBuffer则是可变类,任何对它所指代的字符串的改变都不会产生新的对象。既然可变和不可变都有了,为何还有一个StringBuilder呢?相信初期的你,在进行append时,一般都会选择StringBuffer吧!

先说一下集合的故事,HashTable是线程安全的,很多方法都是synchronized方法,而HashMap不是线程安全的,但其在单线程程序中的性能比HashTable要高。StringBuffer和StringBuilder类的区别也是如此,他们的原理和操作基本相同,区别在于StringBufferd支持并发操作,线性安全的,适 合多线程中使用。StringBuilder不支持并发操作,线性不安全的,不适合多线程中使用。新引入的StringBuilder类不是线程安全的,但其在单线程中的性能比StringBuffer高。

注意:不必考虑到线程同步问题,我们应该优先使用StringBuilder类;如果要保证线程安全,自然是StringBuffer。

          效率:StringBuilder>StringBuffer>String

 

相关面试题:

1)String是最基本的数据类型吗?

基本数据类型包括byte,int, char ,long ,float ,double ,boolean和short.

String是引用数据类型

java.lang.String类是final类型的,因此不可以继承这个类,不能修改这个类,为了提高效率节省空间,我们应该用StringBuffer / StringBuilder类

2)String和StringBuffer的区别

这两个类都实现了CharSequence接口。

(1)类型不同,因为不是一个类,也没有继承关系,做参数时不能共用

(2)String对象是不可变对象,不能修改值。而StringBuffer是可变对象,能修改值。

(3)拼接字符串时,String会产生新对象,而StringBuffer只是增加新字符,不产生新对象,因此效率高。

(4)String覆盖了equals方法和hashCode方法,而StringBuffer没有覆盖equals方法和hashCode方法,所以,将StringBuffer对象存储进Java集合类中会出现问题。

 

posted on 2017-08-14 17:31  左夕  阅读(514)  评论(0编辑  收藏  举报

导航