• 6、字符串


         

    6.1 String 字符串

    JVM为了更高效地处理数据,会用不同的算法把内存分为各种区域,不同的区域拥有各自的特性,Java中,内存可以分为栈,堆,静态域和常量池等。

    • 栈:存放局部变量(变量名,对象的引用等)特点:内存随着函数的调用而开辟,随着函数调用结束而释放。
    • 堆:堆区:存放对象(也就是new出来的东西)特点:可以跨函数使用,每个对象有自己对应的存储空间。
    • 静态域:存放在对象中用static定义的静态成员。
    • 常量池:存放常量。(常量池指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。)

       

    Java字符串就是Unicode字符序列。Java没有内置的字符串类型,而是在标准的Java类库中提供了一个预定义类(String)。

    每个用双引号括起来的字符串都是String类的一个实例:

    String a = "";//这是一个字符串

            String get = "Hello";

    这种方式的定义的String,引用get,存放在栈区。字符串常量"Hello"被存放在常量池引用get引用指向了常量池中俄"Hello"

    String str = new String("new Hello World!");//被存放在堆区

    这种方式定义的String,引用str,存放在栈区,字符串"new Hello World!"存放在堆区

    内存图

    两者的区别:

    第一种:常量池的字符串常量,不能重复出现,也就是说,在定义多个常量时,编译器先去常量池查找该常量是否已经存在,如果不存在,则在常量池创建一个新的字符串常量;如果该常量已经存在,那么新创建的String类型引用指向常量池中已经存在的值相同的字符串常量,也就是说这是不在常量池开辟新的内存

    第二种:在堆中创建新的内存空间,不考虑该String类型对象的值是否已经存在。换句话说:不管它的 只是多少,第二种方法的这个操作已经会产生的结果是:在堆区开辟一块新的内存,用来存放新定义的String类型的对象

         

    6.1.1子串

    String类的 substring() 方法可以从一个较大的字符串中提起出一个子串。

    String greeting = "Hello World!"; //原字符串

            String s = greeting.substring(0,5);// substring(int startIndex,int endIndex); 取值区间为[starIndex,endIndex)

    substring(int starIndex,int endIndex) 是从基字符串的startIndex 位置开始复制 到endIndex 位置,但是不包括endIndex位置的字符

    优点:子字符的长度容易计算:长度=endIndex – startIndex;

    6.1.2 拼接

        Java允许使用'+'连接(拼接)两个字符串。

    常用示例:

    String greeting = "Hello World!";

    System.out.println("这是一个字符串"+greeting);//可以使用+连接两个字符串

    6.1.3不可变字符串

         

    String对象是不可变的。String类中每一个看起来会修改String值得方法实际上都是创建一个全新的String对象,以包含后的字符串内容。而最初的String对象丝毫未动。

    以substring(int startIndex,int endIndex)方法的源码为例:

    public String substring(int beginIndex, int endIndex) {

    if (beginIndex < 0) {

    throw new StringIndexOutOfBoundsException(beginIndex);

    }

    if (endIndex > value.length) {

    throw new StringIndexOutOfBoundsException(endIndex);

    }

    int subLen = endIndex - beginIndex;

    if (subLen < 0) {

    throw new StringIndexOutOfBoundsException(subLen);

    }

    return ((beginIndex == 0) && (endIndex == value.length)) ? this

    : new String(value, beginIndex, subLen);

    }

         

    可以发现当产生字符串时,是产生了一个新的String对象返回。

    6.1.4检测字符串是否相等

    • 使用equals方法来检测两个字符串时否相等

      表达式: s.equals(t) 如果字符串s与字符串t则返回true;否则返回false。

      S与t可以是字符串变量,也可以是字符串常量 。

      String greeting = "Hello World!";

      "Hello World!".equals(greeting);//合法

           

           

    • 使用equalsIgnoreCase方法,不区分大小写检测两个字符串是否相等。

      String greeting = "Hello World!";

      System.out.println("hello world!".equalsIgnoreCase(greeting));//不区分打小写的比较两个字符是否相等

           

    • 不能使用 == 符号判断两个字符串是否相等。这个运算符是只能够确定两个字符串是否放在同一个位置上。如果是放在同一位置上那么就相等

      String greeting = "Hello World!"; //原字符串

      String s = greeting.substring(0,5);

      String get ="Hello";

      System.out.println("使用==比较两个不共享字符串:"+(get==s));

      System.out.println("使用==比较两个共享字符串:"+("Hello World!"=="Hello World!"));

    实际上只有字符串常量是共享的,而+活substring的操作产生的字符串时不共享的。

    6.1.5空串与null

    • 空串 ""是长度为0的字符串

      判断字符串是否为空串 str.length == 0 或str.equals("")

    • 字符串还可以存放null值,当为字符串为 null时,不能调用方法

      判断是否 为null

      null == str

           

    String empty = "";

            System.out.println("empty是否为空串:"+("".equals(empty)));

            String nullStr = null ;

            System.out.println("nullStr是否为null"+(nullStr == null));

        nullStr.equals("");//编译时正确,运行时抛出异常: java.lang.NullPointerException.原因:nullStr null

    6.1.6 String类API

    下面 是一些常用的String类方法介绍:

    • char charAt(int index)

      返回给定位置的字符。

    • int compareTo(String other)

      按字典顺序,如果字符串位于other之前返回负数;如果字符串位于other之后,返回一个正数;如果两个字符串相等,返回0。

    • boolean endsWith(Stirng suffix)

      如果字符串以suffix结尾,返回true

    • int length()

      返回字符串的长度

    • String replace(CharSequence oldString, CharSequence newString)

      返回一个新的字符串,这个字符串用newString代替原始字符串中所有的oldString。可以用String或StringBuilder对象作为CharSequence参数

    • boolean startsWith(String suffix)

      如果字符串以suffix开始,返回true

    • String toLowerCase()

      返回一个新的字符串,把字符串所有的字符转化为小写

    • String toUpperCase()

      返回一个新的字符串,把字符串所有的字符转化为大写

    • String trim()

      返回一个新的字符串,去除字符串中头部和尾部的空格  

      示例:

      步骤1,在Demo010项目的com.zjk.type包下创建StudyString类

      源码:

    package com.zjk.type;

    public class StudyString {

            

        public static void main(String[] args) {

                

            String greeting = "Hello World!"; //原字符串

            String get ="Hello";

            String s = greeting.substring(0,5);// substring(int startIndex,int endIndex); 取值区间为[starIndex,endIndex)

            System.out.println(s);      

            System.out.println("这是一个字符串"+greeting);//可以使用+连接两个字符串

            System.out.println("比较两个字符串是否相等:"+("Hello World!".equals(greeting)));//合法

            System.out.println("使用==比较两个不共享字符串:"+(get==s));

            System.out.println("使用==比较两个共享字符串:"+("Hello World!"=="Hello World!"));

            System.out.println("不区分大小写比较两个字符串是否相等:"+("hello world!".equalsIgnoreCase(greeting)));//不区分打小写的比较两个字符是否相等

                

            String empty = "";//这是一个字符串

            System.out.println("empty是否为空串:"+("".equals(empty)));

            String nullStr = null ;

            System.out.println("nullStr是否为null"+(nullStr == null));

    //        nullStr.equals("");//编译时正确,运行时抛出异常: java.lang.NullPointerException.原因:nullStr null

       

            /* API */

            String ss = " Hello World!"; //原始字符串

            System.out.println("ss字符串的长度为:"+(ss.length()));

            System.out.println("ss的第3个字符为:"+(s.charAt(3)));

            System.out.println(""kl"字符串在与ss字符串排序比较"+(ss.compareTo("kl")));

            System.out.println("ss字符串是否是以"!"结尾"+(ss.endsWith("!")));

            System.out.println("ss字符串是否是以" "开始"+(ss.startsWith(" ")));

            System.out.println(""hello world!"代替ss字符串中的"Hello World""+(ss.replace("Hello World!", "hello world!")));

            System.out.println("ss字符串全部变为大写:"+(ss.toUpperCase()));

            System.out.println("ss字符串全部变为小写:"+(ss.toLowerCase()));

            System.out.println("去除ss字符串头部和尾部的空格:"+(ss.trim()));  

        }

         

    }

         

    6.2可变字符StringBuilder和StringBuffer

         

    6.2.1 StringBuilfer

        每次连接字符串,都会构建一个新String对象,即耗时又浪费空间使用StringBuilder类可以避免这个问题的发生

    第一:构建字符串构建器:

    StringBuilder builder = new StringBuilder();//一个空的字符串构造器

            StringBuilder builder2 = new StringBuilder("Hello");//一个有初始值的字符串构造器

        第二: 需要添加内容时,调用append方法

    builder.append("hello");//在字符串的后面添加一个字符串

    第三:需要显示是调用toString方法

    System.out.println(builder.toString());//输入

    API文档:

    • int length()

      返回字符长度

    • void setCharAt(int I,char c)

      将第i位置的字符设置为c

    • StringBuilder insert(int offset,String str)

      在oddset位置插入字符str并返回插入后字符构建器

    • StringBuilder delete(int startIndex,int endIndex)

      删除startIndex位置到endIndex-1位置的字符串并返回删除后的字符构造器

      示例:

      步骤1: 在Demo010项目的com.zjk.type包下创建StudyStringBuilder类

      源码:

    package com.zjk.type;

    /**

    *

    *@类名 StudyStringBuilder

    *@日期 20151129日下午3:04:34

    *@作者 zjkorder

    *@版本 v1.0

    *@描述    

    * StringBuilder类的学习

    * main方法所在类

    */

    public class StudyStringBuilder {

        public static void main(String[] args) {        

            StringBuilder builder = new StringBuilder();//一个空的字符串构造器

            StringBuilder builder2 = new StringBuilder("Hello");//一个有初始值的字符串构造器

            builder.append("hello");//在字符串的后面添加一个字符串

            System.out.println(builder.toString());//输入

            System.out.println("字符构建器的长度为:"+builder.length());

            builder.setCharAt(0, 'H');//将第0位置的h更改为H

            System.out.println("更改后的字符串为:"+builder.toString());

            builder = builder.insert(0, 'h');//在第0位置插入h

            System.out.println("更改后的字符串为:"+builder.toString());

            builder = builder.delete(1, 2);//删除第1位置到2-1位置的字符

            System.out.println("更改后的字符串为:"+builder.toString());

        }

    }

         

    6.2.2 StringBuffer

       在讲解StringBuffer类之前先来回顾一下String类特点:

    一个字符串常量就是String类的匿名对象;

    String类对象有两种实例化方式:

                          |-方式一:直接赋值,可以自动入池,只开辟一块内存空间;

                          |-方式二:构造方法实例化,会开辟两块空间,其中一块将成为垃圾,不会自动入池,可以使用intern()方法手工入池;

    ·字符串内容一旦声明则不可改变。

          正是因为字符串内容一旦声明不可改变,所以如果在频繁修改字符串内容的程序上是不能够使用String的,那么为此在Java之中又提供有一个StringBuffer类,而String和StringBuffer类最大的特征在于:String不可改变内容,而StringBuffer可以改变。在String类对象之中使用"+"可以实现字符串连接操作,但是在StringBuffer类之中只能够使用append()方法实现字符串连接:public StringBuffer append(数据类型b)。既然返回的是StringBuffer就可以一直使用append()连接。

    跟StringBuilder类的方法组相似。

    6.2.3 String StringBuilder和StringBuffer的比较

    String、StringBuffer、StringBuilder的区别:

    • String不适合于字符串的频繁修改,而StringBuffer和StringBuilder适合于频繁修改,而且速度要远远高于String;
    • StringBuffer是在JDK  1.0的时候引入的,而StringBuilder是在JDK  1.5的时候引入的,而且StringBuffer和StringBuilder继承结构相同,方法的组成也相同;
    • StringBuffer中的所有方法都使用synchronized进行标记,都是同步方法,性能相对较低,而StringBuilder采用的异步处理,性能相对较高,但是StringBuffer在多线程操作时的数据安全性要高于StringBuilder。

    6.3输入

    需要在控制台输入需要Scanner的对象。

    System.out 是标准输出流那么System.in 就是标准输入流

    第一:构建Scanner对象

    Scanner input = new Scanner(System.in);//构建控制台接收对象

    第二:读取读取输入的一行数据

    String ss = input.nextLine();//接收控制台输入的一行数据并保存到SS字符串中

    第三: 关闭Scanner

    input.close();//关闭控制台的接收器

       

    Scanner 的常用方法有:

    • String next()

      读取输入的单词以空格作为分割

    • Int nextInt()

      读取输入的整数返回int型数据

    • double nextDouble()

      读取输入的浮点数

    • boolean hasNext()

      检测输入中是否还有其他单词

    • boolean hasNextInt()

      检测输入中是否还有其他整数

    • boolean hasNextDouble()

      检测输入中是否还有其他浮点数

  • 相关阅读:
    Redis 服务端程序实现原理
    Redis 中的客户端
    Redis 中的数据持久化策略(AOF)
    Redis 中的数据持久化策略(RDB)
    Redis 中的数据库
    Redis 的底层数据结构(对象)
    Redis 的底层数据结构(压缩列表)
    Redis 的底层数据结构(整数集合)
    又离职了~
    如何救活被屏蔽的主机,继续开发工作
  • 原文地址:https://www.cnblogs.com/zjkorder/p/5004773.html
Copyright © 2020-2023  润新知