6.1 String 字符串

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

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

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

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

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

get"Hello";

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

String strnew"new Hello World!");//被存放在堆区

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

内存图

java字符串存在哪里 java 字符串存在什么区域_java字符串存在哪里

两者的区别:

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

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

     

6.1.1子串

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

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

sgreeting.substring(0,5);// substring(int startIndex,int取值区间为[starIndex,endIndex)

java字符串存在哪里 java 字符串存在什么区域_System_02

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)方法的源码为例:

publicsubstring(intbeginIndex, intendIndex) {
													
			
ifbeginIndex
							
			
thrownewbeginIndex);
									
			
}
		
ifendIndexvalue.length) {
											
			
thrownewendIndex);
									
			
}
		
intsubLenendIndexbeginIndex;
											
			
ifsubLen
							
			
thrownewsubLen);
									
			
}
		
returnbeginIndexendIndexvalue.length)) ? this
														
			
: newvalue, 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 sgreeting.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"";
								
			
out.println("empty是否为空串:"+("".equals(empty)));
											
					
nullStrnull
								
			
out.println("nullStr是否为null:"+(nullStrnull));
												
					
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
					
			
publicclass
							
			
      
 
publicstaticvoidargs) {
												
			
          
 
greeting"Hello World!"; //原字符串
					
			
get"Hello";
								
			
sgreeting.substring(0,5);// substring(int startIndex,int取值区间为[starIndex,endIndex)
						
					
out.println(s);
								     
		
out.println("这是一个字符串"+greeting);//可以使用+连接两个字符串
								
							
out.println("比较两个字符串是否相等:"+("Hello World!".equals(greeting)));//合法
							
						
out.println("使用==比较两个不共享字符串:"+(get==s));
												
					
out.println("使用==比较两个共享字符串:"+("Hello World!"=="Hello World!"));
												
					
out.println("不区分大小写比较两个字符串是否相等:"+("hello world!".equalsIgnoreCase(greeting)));//不区分打小写的比较两个字符是否相等
							
						
          
 
empty"";//这是一个字符串
					
			
out.println("empty是否为空串:"+("".equals(empty)));
											
					
nullStrnull
								
			
out.println("nullStr是否为null:"+(nullStrnull));
												
					
//        nullStr.equals("");//编译时正确,运行时抛出异常: java.lang.NullPointerException.原因:nullStr 为null
			
		
 
 
/* API */
					
			
ss" Hello World!"; //原始字符串
					
			
out.println("ss字符串的长度为:"+(ss.length()));
									
					
out.println("ss的第3个字符为:"+(s.charAt(3)));
										
					
out.println("\"kl\"字符串在与ss字符串排序比较"+(ss.compareTo("kl")));
												
					
out.println("ss字符串是否是以\"!\"结尾"+(ss.endsWith("!")));
												
					
out.println("ss字符串是否是以\" \"开始"+(ss.startsWith(" ")));
												
					
out.println("用\"hello world!\"代替ss字符串中的\"Hello World!\""+(ss.replace("Hello World!", "hello world!")));
														
					
out.println("ss字符串全部变为大写:"+(ss.toUpperCase()));
									
					
out.println("ss字符串全部变为小写:"+(ss.toLowerCase()));
									
					
out.println("去除ss字符串头部和尾部的空格:"+(ss.trim()));
										 
				
    }
		
   
 
}

     

6.2可变字符StringBuilder和StringBuffer

     

6.2.1 StringBuilfer

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

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

StringBuilder buildernew//一个空的字符串构造器

builder2new"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

/**

*

*@类名 StudyStringBuilder

*@日期 2015年11月29日下午3:04:34

*@作者zjkorder

*@版本 v1.0

*@描述    

* StringBuilder类的学习

* main方法所在类

*/

publicclass

publicstaticvoidargs) {        

buildernew//一个空的字符串构造器

builder2new"Hello");//一个有初始值的字符串构造器

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

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

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

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

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

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

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

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

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 inputnewin);//构建控制台接收对象

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

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

第三: 关闭Scanner

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

   

Scanner 的常用方法有:

  • String next() 读取输入的单词以空格作为分割
  • Int nextInt() 读取输入的整数返回int型数据
  • double nextDouble() 读取输入的浮点数
  • boolean hasNext() 检测输入中是否还有其他单词
  • boolean hasNextInt() 检测输入中是否还有其他整数
  • boolean hasNextDouble() 检测输入中是否还有其他浮点数