Java程序设计

第三章 数组和字符串(2)

字符串类(String)

  • 一串字符,用双引号表示字符串常量,用String存储字符串常量
  • 
    String s1 = "hello World!";
    String s2 = new String( "Hello, World" );
                            
  • String类有丰富的方法用于字符串操作
  • 
    String s1 = "Hello";
    s1.length();
    s1.charAt( 0 );//可将字符串理解为字符数组
                            
  • Java内建了对字符串的支持,可直接对字符串常量调用与String类同样的方法
  • 
    "Hello World".length();
    " hello  ".trim();
                            

String类常用方法(一)

String类常用方法(一)

  • length()方法, 注意和数组的length属性区别
  • 
    String str = "Welcome to Java";
    System.out.println( "The length of " + str + " is " + str.length() );
                                
  • charAt(index)方法,返回字符串在指定位置上的字符
  • 
    String str = "Welcome to Java";
    int index = 0;
    System.out.println( "The " + index + "th character of " + str + " is " + str.charAt( index ) );
                                
  • concat()方法,连接两个字符串,构成一个新的字符串
  • StringConcatTest.java

String类常用方法(一)

  • toLowerCase和toUpperCase()方法,实现字符串的大小写转换
  • 
    String s1 = "welcome";
    String s2 = "WELCOME";
    System.out.println( "s1 to upper case: " + s1.toUpperCase() );
    System.out.println( "s2 to lower case: " + s2.toLowerCase() );
                                
  • trim()方法,去除字符串头尾部的空白,包括"\t, \n, \f, \r"和空格
  • 
    String s3 = "\t Good Night \n";
    System.out.println( s3.trim() );
                                
  • split()方法,将字符串根据给定字符分割成字符串数组
  • 
    String s4 = " H E L L O ";
    String[] strs = s4.split( " " );
    for( String str:strs )
      System.out.print( str );
                                

从标准输入获取字符串和字符

  • 输入字符串,利用Scanner类的next()和nextLine()方法
  • 
    Scanner input = new Scanner( System.in );
    String s1 = input.next();
    String s2 = input.next();
    String s3 = input.next();
    System.out.println( "s1 + s2 + s3 is " + s1 + s2 + s3 );
    
    System.out.print( "enter a line" );
    String s = input.nextLine();
    System.out.println( "s is " + s );
                                
  • 从标准输入获取字符,利用字符串的charAt(index)方法
  • 
    Scanner input = new Scanner( System.in );
    String s = input.nextLine();
    char ch = s.charAt( 0 );
    System.out.println( "The character is " + ch );
                                

String类常用方法(二)

String类常用方法(二)

  • equals和equalsIgnoreCase方法,比较两个字符串内容是否相同
  • 
    String s1 = "Welcome";
    String s2 = "Welcome";
    String s3 = "welcome";
    System.out.println( s1.equals( s2 ) );
    System.out.println( s1.equals( s3 ) );
    System.out.println( s1.equalsIgnoreCase( s3 ) );
                                
  • compareTo和compareToIgnoreCase方法,比较两个字符串的内容,返回整数表示二者大小关系,>0表示大于,0表示相等,<0表示小于
  • 
    System.out.println( s1.compareTo( s2 ) );
    System.out.println( s1.compareTo( s3 ) );
    System.out.println( s1.compareToIgnoreCase( s3 ) );
                                

String类常用方法(二)

  • startsWith和endsWith方法,计算一个字符串是否以特定的字符串开头或结尾
  • 
    System.out.println( s1.startsWith( "We" ) );
    System.out.println( s1.startsWith( "we" ) );
    System.out.println( s2.endsWith( "me" ) );
                                
  • contains方法,判断一个字符串是否包含某特定字符串
  • 
    System.out.println( s1.contains( "lco" ) );
    System.out.println( s1.contains( "LCO") );
                                

String类常用方法(三)

String类常用方法(四)

  • substring方法,获得字符串的子串,注意方法名的写法
  • 
    String str = "Welcome to Java";
    String substr1 = str.substring( 4 );
    String substr2 = str.substring( 0, 11 ) + "HTML";
    System.out.println( substr1 );
    System.out.println( substr2 );
                                
  • indexOf和lastIndexOf方法,注意方法的不同参数使用
  • 
    System.out.println( str.indexOf( 'W' ) );
    System.out.println( str.indexOf( 'o' ) );
    System.out.println( str.indexOf( 'o', 5 ) );
    System.out.println( str.indexOf( "come" ) );
    System.out.println( str.indexOf( "Java", 5 ) );
    System.out.println( str.indexOf( "java", 5 ) );
    System.out.println( str.lastIndexOf( 'W' ) );
    System.out.println( str.lastIndexOf( 'o' ) );
    System.out.println( str.lastIndexOf( 'o', 5 ) );
    System.out.println( str.lastIndexOf( "come" ) );
    System.out.println( str.lastIndexOf( "Java", 5 ) );
    System.out.println( str.lastIndexOf( "java", 5 ) );
                                

基本数据类型的包装类

针对八种基本数据类型,提供对应的包装类,用于实现类型间转换,如数字与字符串间的转换;也可作为参数传入相应方法,如各种泛型类方法,要求参数类型为Object类,基本数据类型无法传入

  • byte → Byte
  • char → Character
  • short → Short
  • int → Integet
  • long → Long
  • float → Float
  • double → Double
  • boolean → Boolean

基本数据类型的包装类

  • 包装类和基本数据类型之间的转换,以int和integer为例
  • 
    int n = 10;
    Integer N = new Integer( n );
    int m = N.intValue();
                                
  • JDK 1.5以后提供了自动装箱和拆箱的机制,当表达式中出现基本数据类型与包装类转换需求时,会自动进行转换
  • 
    Integer N = 100; // 自动装箱,相当于new Integer(100)
    int n = N; // 自动拆箱,相当于N.intValue();
                                

字符串与数字间的转换

  • 字符串与数值之间转换,可采用相应包装类的静态方法,以int和Integer为例
  • 字符串转换为int,采用Integer.parseInt方法
  • 
    String s = "1234";
    int n1 = Integer.parseInt( s );
    int n2 = Integer.parseInt( s, 10 );
    int n3 = Integer.parseInt( s, 16 );
    int n4 = Integer.parseInt( "0101", 2 );
                            
  • 字符串转换为Integer,采用Integer.valueOf方法
  • 
    Integer n1 = Integer.valueOf( s );
    Integer n2 = Integer.valueOf( s, 16 );
    Integer n3 = Integer.valueOf( "0101", 2 );
                            
  • 数字转换为字符串,用Integer.toString方法
  • 
    String s = Integer.toString( 1000 );
                            

栈和堆

  • 栈和堆都是内存中的区域,用于存放不同类型的数据
  • 基本数据类型的值存储在
  • 引用数据类型的引用变量存储在中,具体的数据存储在中,由引用变量指向堆中的内容
  • 凡用new生成的对象或数组,其变量名存储在栈中,其对象或数组的具体内容存储在堆中

栈和堆

==和equals

  • 当用"=="进行比较时,比较的是存储在中存储的变量值
  • 基本数据类型值可直接使用"=="进行比较
  • 对引用数据类型,若使用“=="进行比较,比较的是引用数据类型对象的引用地址
  • 对引用数据类型,使用equals方法进行比较,比较的是引用数据类型对象存储在堆中的具体内容
  • 引用数据类型都有equals方法可进行比较,基本数据类型只能使用"=="进行比较
  • EqualTest.java

字符串创建机制

字符串池

字符串池机制

  • 字符串池,在“堆”内存中,用于存储已创建的字符串对象
  • 当调用String s="hello"时,首先在字符串池中寻找是否已存在此字符串,若有,就将其赋值给s变量(如何解释?);若不存在,则在堆中新建一个字符串,记录其地址值,将其地址值赋值给变量s
  • 
    String s1 = "hello";
    String s2 = "hello";
    String s3 = new String( "hello" );
    System.out.println( "s1==s2? " + (s1==s2) + ", s1==s3? " + (s1==s3) );
    System.out.println( "s1.equals(s2)? " + s1.equals( s2 ) + ", s1.equals(s3)? " + s1.equals(s3) );
                                

字符串池机制(续)

  • 字符串池中的字符串是常量,一经创建后不能改变其值
  • 
    String s1 = "hello";
    System.out.println( s1.hashCode() );
    System.out.println(System.identityHashCode(s1));
    s1 = "hello2";
    System.out.println( s1.hashCode() );
    System.out.println(System.identityHashCode(s1));
                                

    StringPoolTest.java

  • String对象的实例是不可改变的,任何字符串操作都会生成新的实例,原有字符串并未发生改变
  • String是一个对象,不是字符数组,末尾没有'\0'

StringBuffer类

  • String类对象实例是不可改变的,若要改变String对象本身的内容,可采用StringBuffer类
  • 
    StringBuffer sb = new StringBuffer( "Hello" );
    int i = 101;
    sb.append( " " ).append( "World" ).append( i ); //可任意添加
    String str = sb.toString();
                                

    StringBufferTest.java

  • 与使用"+"进行字符串连接相比,StringBuffer直接使用字符数组对内容进行动态扩充,性能要好很多
  • StringBuilder能够提供与StringBuffer类似的功能,但StringBuffer是线程安全的,但StringBuilder不是