• java基础知识(二)字符串处理


      字符串是程序开发中使用最为频繁,因此为了工作的高效和作为一名想进阶的程序员,了解并掌握字符串的处理显得尤为重要。java为我们提供了String、StringBuffer、StringBuilde三个处理字符串的类,下面我们对其做一个总结和介绍。

    1、分别介绍

      1)String

      解答1:

      我们在查看API文档的时候,会发现有这么一句话“字符串是常量,它们的值在创建之后不能更改”。众所周知常量是用final修饰的,一旦创建在程序的其他地方无法修改。这时我们就会快速的回想,在我们日常的开发中String是可以随时随地可对其赋值的,难道是jdk的API文档写错了?其实不然,下面我们对其原理进行讲解。

    
    
    public static void main(String arg[]){
    String str1 = "a";
    String str2 = str1;
    String str4 = str2;
    System.out.println(str1 == str2);//true,说明引用stt1和引用str2指向了同一地址
    String str3 = "b";
    str1 = str1 + str3;
    System.out.println(str1 == str2);//false,说明引用str1所指向的地址已经改变
    System.out.println(str2 == str4);//true
    str2 = str2 + str3;
    System.out.println(str2 == str4);//false,说明引用str2所指向的地址已经改变
    System.out.println(str1 == str2);//false
    }
    
    

      因为String是引用类型,引用类型在内存中的存储如下图

      

      也就是说,当我们在对str1做改变的时候,只是改变了其在栈内存中存储的引用所指向的地址,与此同时java虚拟机会为其在堆内存中重新分配新的空间,而原来堆内存地址存储的值(因为是常量)并没有发生改变,会作为无用的引用被java回收站处理,到此相信可以顺利理解上述代码。

      解答2:

    public class Test {

    private final static String s1 = "abc";
    private final static String s2 = "abc";

    public static void main(String arg[]){
    String str1="abc";
    String str2="abc";
    String str3="ab"+"c";
    String str4=new String(str2);
    System.out.println(str1 == str2);//true,说明str1、str2指向同一地址
    System.out.println(str1 == str3);//true,说明str1、str3指向同一地址
    System.out.println(str1 == str4);//false,说明str1、str4指向不同的地址
    System.out.println(s1 == s2);//true,说明s1、s2指向同一地址
    System.out.println(str1 == s1);//true,说明str1、s1指向同一地址
    }

    }

        上述现象是有常量在内存中的存储规则决定的,java代码在编译的阶段会在代码区中分配出一块存储区域,作为常量池,用于存储常量值。当再有常量被申明时,编译器会去常量池中查找这个字符串是否存在,若存在则将这个字符串的引用直接指向字符串所在地址,否则为其在常量池中分配新的空间,也就是说所有值相同的常量的引用会指向同一个存储地址。至于str4是编译器为其new了新的存储空间,将其作为对象处理,而不是常量。

      下面给出常量的内存中的存储分配

      

      注意:stack为栈,Heap为堆,Method Area为方法区,也即代码区。

      解答3:String的常用方法

      equals(Object anObject)和equalsIgnoreCase(String anotherString):equals是开发中使用非常频繁的方法,需要区分equals和“==”所比较的对象,equals比较的是两个对象(引用)的值是否相等,“==”比较的对象既可以是基本数据类型,也可以是引用类型,当比较对象为基本数据类型时就是值的比较,当比较对象是引用类型的时候比较的是引用(引用所指的地址),而不是引用所指向的值。后者是不考虑大小写的比较。

      contentEquals(CharSequence cs)、contentEquals(StringBuffer sb):字符串与指定的CharSequence/StringBuffer比较。

      compareTo(String anotherString) 和compareToIgnoreCase(String str) :按字典顺序比较两个字符串,后者忽略大小写。

          matches(String regex):当前字符串是否匹配给定的正则表达式。

          length():返回次字符串的长度

      isEmpty():当且仅当 length() 为 0 时返回 true

          split(String regex)、split(String regex, int limit) :据给定正则表达式拆分字符串

      substring(int beginIndex) 、substring(int beginIndex, int endIndex):按规则返回此字符串的子字符串

      replace(char oldChar, char newChar)、replace(CharSequence target, CharSequence replacement)、replaceAll(String regex, String replacement):替换

      valueOf(boolean b)等:返回基本数据类型的字符串表示形式

      valueOf(Object obj):返回Object的字符串形式

      toLowerCase()和toUpperCase():使用默认语言环境将此字符串中的所有字符转换为小写/大写

      toCharArray():将字符串转为字符数组

      contains(CharSequence s) :当且仅当字符串包含指定的char值序列时返回true。

      indexOf(int ch) 、indexOf(int ch, int fromIndex) 、indexOf(String str) 、indexOf(String str, int fromIndex) :按规则返回索引。

      lastIndexOf(int ch) 、lastIndexOf(int ch, int fromIndex)、lastIndexOf(String str)、lastIndexOf(String str, int fromIndex):按规则返回指定字符或字符串最后出现位置的索引。

      concat(String str):指定字符串连接到此字符串的结尾。(一般用+号解决了,所以用的很少)

      trim() :返回字符串的副本,忽略前导空白和尾部空白

      2)StringBuffer

        线程安全的可变字符序列。

      append(String str)等:将字符串追加到此字符串后面

      insert(int offset, String str)等:将字符串插入此字符序列中

      reverse():将此字符序列用其反转形式取代。这是一个非常有用的方法,可方便的将指定字符串逆序输出。

      toString():将StringBuffer串转换为String

      3)StringBuilde

        一个可变的字符序列,基本和StringBuffer相同,但是是非线程安全的,所以效率高于StringBuffer、Stringj。

    2、String、StringBuilde、StringBuffer比较

      1、StringBuilde是非线程安全的,StringBuffer是线程安全的。

      2、效率上String<StringBuffer<StringBuilde

        原因在于String是字符串常量,另外两个是字符串变量,String在每次赋值时都需要new一个新的对象(上面有详细介绍),原有对象会被GC当垃圾回收,会大大降低执行效率。而StringBuffer与StringBuilder是字符串变量,改变发生在同一对象,少了创建、销毁对象环节。

      最后建议,如果操作少量数据则使用String,如果单线程下操作大量数据则用StringBuilder,如果是多线程下操作大量数据则用StringBuffer。

  • 相关阅读:
    nyoj 311 完全背包
    nyoj 737 石子合并(一)
    nyoj 232 How to eat more Banana
    nyoj 456 邮票分你一半
    nyoj 236 心急的C小加
    nyoj 195 飞翔
    nyoj 201 作业题
    SOS 调试扩展 (SOS.dll)
    使用Windbg和SoS扩展调试分析.NET程序
    windbg命令分类与概述
  • 原文地址:https://www.cnblogs.com/sunjf/p/java_charactor_string.html
Copyright © 2020-2023  润新知