JAVASE_13_#JavaAPI_String和StringBuffer

1.String概述------>一旦被初始化就不可改变(final常量的特性)【放在常量池中 】
见CDDN/kkopophttp://blog.csdn.net/kkopopo/article/details/20207495
String s1 =  "" ;
String s2 =  null ;   
System.out.println( "----" +s1+ "****" ); //结果----****s1.length()结果是0
System.out.println( "----" +s2+ "****" ); //结果----null****s2.length()抛异常java.lang.NullPointerException
    1.2,常量
String s1 =  "abc" ; //s1是一个类类型变量,"abc"是一个对象
                  //字符串最大的特点: 一旦被初始化就不可改变(final常量的特性)【放在常量池中 】
    1.3关于"=="和equals(),都是比较的内存地址,但是在一些类库当中这个方法被覆盖掉了,如String,Integer,Date在这些类当中equals有其自身的实现,而不再是比较类在堆内存中的存放地址了。
String tom = "I am student"; 这个是字符串常量,存储在常量池中 
String jerry = "I am student"; 因为在常量池中已有,就不创建新的,直接从常量池中调用,所以一样
tom == jerry ---------true;
tom.equals(jerry)-----true;
//******************************************//
String tom = new String("I am student");
String jerry = new String("I am stundet");
tom == jerry--------false//new产生先对象 ,不相同
tom.equals(jerry)---true//
    1.4**********************************
1
2
3
4
5
6
7
8
9
10
11
12
13
public  class  StringDemo {
     public  static  void  main(String[] args) {
         String s1 = "abc";
        String s2 = new String("abc");
        //s1和s2有什么区别?
        //s1在内存中有一个对象。
        //s2在内存中有两个对象。(可能是1个对象)下面有解析
         System.out.println(s1==s2); //false
         System.out.println(s1.equals(s2)); //true,String类复写了Object类中equals方法,
                                         //该方法用于判断字符串是否相同。
     }
  
}
说到java中堆、栈和常量池,首先还是看看他们各自存放的数据类型吧!

堆:存放所有new出来的对象;

栈:存放基本类型的变量数据和对象的应用,对象(new出来的对象)本身并不存在栈中,而是存放在堆中或者常量池中(字符串常量对象存放在常量池中);

常量池:存放基本类型常量和字符串常量。


对于栈和常量池中的对象可以共享,对于堆中的对象不可以共享。


栈中的数据大小和生命周期是可以确定的,当没有引用指向数据时,这个数据就会自动消失。

堆中的对象的由垃圾回收器负责回收,因此大小和生命周期不需要确定,具有很大的灵活性。


<一>字符创String

而对于字符串来说,其对象的引用都是存储在栈中的.

如果是编译期已经创建好(即指用双引号定义的)的就存储在常量池中,如果是运行期(new出来的对象)则存储在堆中。

对于equals相等的字符串,在常量池中是只有一份的,在堆中则有多份。

String str1="abc";//编译期就创建好了,存在常量池中

String str2="abc";

String str3="abc";

String str4=new String("abc");//运行期new出来的

String str5=new String("abc");

java中的堆、栈和常量池

对于浅蓝色箭头,通过new操作产生一个字符串(“abc”)时,
会先去常量池中查找是否有“abc”对象,如果没有则在常量池中创建一个此字符串对象,
然后堆中再创建一个常量池中此“abc”对象的拷贝对象,
所以,对于String str=new String("abc"),如果常量池中原来没有"abc"则产生两个对象,否则产生一个对象。

<二>基本类型和基本类型的常量
变量和引用变量--------变量和引用存储在栈中
常量:-------------存储在常量池中

int a1 = 1, a2 = 1, a3 = 1;
public static final int INT1 = 1;
public static final int INT2 = 1; 
public static final int INT3 = 1;
java中的堆、栈和常量池

<三>成员变量和局部变量
对于成员变量和局部变量来说,
成员变量是方法外部,类得内部定义的变量;
局部变量就是方法或语句块内部定义的变量,注意,局部变量必须初始化。
局部变量(形式参数)的数据存于栈内存中,并且它(局部变量)随方法的消失而消失。




我们的程序里不可避免大量使用字符串处理,避免使用String,应大量使用StringBuffer

因为String被设计成不可变(immutable)类,所以它的所有对象都是不可变对象,请看下列代码;

  
  
  1. String s = "Hello";
  2. = s + " world!";
  3. String s = "Hello";
  4. s = s + " world!";

在这段代码中,s原先指向一个String对象,内容是”Hello”,

然后我们对s进行了+操作,那么s所指向的那个对象是否发生了改变呢?

答案是没有。这时,s不指向原来那个对象了,而指向了另一个String对象,内容为”Hello world!”;

原来那个对象还存在于内存之中,只是s这个引用变量不再指向它了。


通过上面的说明,我们很容易导出另一个结论,

如果经常对字符串进行各种各样的修改,或者说,不可预见的修改,那么使用String来代表字符串的话会引起很大的内存开销

因为String对象建立之后不能再改变,所以对于每一个不同的字符串,都需要一个String对象来表示。

这时,应该考虑使用StringBuffer类,它允许修改,而不是每个不同的字符串都要生成一个新的对象。

并且,这两种类的对象转换十分容易。




2.创建功能方法---------------****笔试面试有****
                     -----必须熟练掌握到不参照API和Eclipse工具独立写出,否则面试官不相信你有编程经验
1:获取
1.1  int  length() //数组中也有但是属性arr.length,这个是方法
1.2  char  charAt() // str.chatAt(4)=='c';不是""是''
                 //sop(str.charAt(4);//当访问到字符串中不存在的角标时会发生StringIndexOutOfBoundsException。
1.3  int  indexOf( int  ch) //ch在字符串中第一次出现的位置
     int  indexOf( int  ch, int  fromIndex) //从fromIndex指定位置开始,获取ch在字符串中出现的位置
                                     //str.indexOf('m',3));//如果没有找到,返回-1.
     int   indexOf (String str)
     int  indexOf(String str, int  fromIndex)
     int  lastIndexOf( int  ch) //反向索引一个字符出现位置,注意字符的角标固定无论正向反向
2:判断
2.1   boolean   contains()**
//特殊之处:indexOf(str):可以索引str第一次出现位置,如果返回-1.表示该str不在字符串中存在。
                        //所以,也可以用于对指定判断是否包含。
                        //if(str.indexOf("aa")!=-1)
                        //而且该方法即可以判断,有可以获取出现的位置。
2.2  boolean  isEmpty()
2.3  boolean  startsWith(str)
2.4  boolean  endsWith(str)
2.5  boolean  equals(str) //复写了Object类中的equals方法。
2.6   boolean   equalsIgnoreCase() //判断内容是否相同,并忽略大小写。 用户登录
3:转换
3.1  构造方法:将字符数组转成字符串
     String(Byte[])//默认字符集
    String( Byte[ ],charsetName)//制定字符集,把字节转换成String

     String( char [])
     String( char [],offset,count) //将字符数组中的一部分转成字符串。
     静态方法:
     static  String copyValueOf( char []) //将返回指定数组中表示该字符序列的String
     static  String copyValueOf( char [] data,  int  offset,  int  count)
     static  String valueOf( char []):
3.2   char[] toCharArray(): // ** 将字符串转成字符数组
String s1 = "zxcvbnm" ;
char[] chs = s1.toCharArray();
3.3  String( byte [])
     String( byte [],offset,count):将字节数组中的一部分转成字符串。
3.4   byte[]  getBytes()://把String转化成字节数组byte[],和toCharArray()不同
    byte []  getBytes(charsetName): //带字符集
3.5  static  String valueOf( int )
     static  String valueOf( double )
     //形式1:3+"";
     //形式2:String.valueOf(3);// 特殊:字符串和字节数组在转换过程中,是可以指定编码表的
     //形式3:Integer.toString( 34 ); //将整数34变成“34”
4:替换
4.1   String replace(oldchar,newchar);//与StringBuffer的返回值类型不同.
//StringBuffer replace(int start, int end, String str) 
     String s =  "hello java" ;
     String s1 = s.replace( 'q' , 'n' ); //如果要替换的字符不存在,返回的还是原串。
     String s1 = s.replace( "java" , "world" );
         sop( "s=" +s); //s不变,因为字符串一旦初始化就不可以改变
         sop( "s1=" +s1); //hello world
5:切割
5.1  String[] split(regex);
     String s =  "zhagnsa,lisi,wangwu" ;
     String[] arr  = s.split( "," ); //切割符不会出现在数组中
6:子串。获取字符串的一部分
6.1  String substring(begin); 从指定位置开始到结尾。如果角标不存在,会出现字符串角标越界异常。
     String substring(begin,end); //end是角标值,不是个数包含头,不包含尾。s.substring(0,s.length());
7:转换,去除空格,比较
7.1  String toUpperCase();
     String toLowerCase();
7.2  String trim(); //去除字符串两边的空格,字符串中间的空格不会去除
7.3  int  compareTo(string); //返回值是ASCLL值得差值
     String s1 =  "a1c" ;
     String s2 =  "aaa" ;
     sop(s1.compareTo(s2)); //返回值是-48=49('1')-97('a')



3.String函数练习

2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
1 ,模拟一个trim方法,去除字符串两端的空格。
     思路:
     1 ,判断字符串第一个位置是否是空格,如果是继续向下判断,直到不是空格为止。
         结尾处判断空格也是如此。
     2 ,当开始和结尾都判断到不是空格时,就是要获取的字符串。
//===================================================================
2 ,将一个字符串进行反转。将字符串中指定部分进行反转, "abcdefg" ;abfedcg
     思路:
     1 ,曾经学习过对数组的元素进行反转。
     2 ,将字符串变成数组,对数组反转。
     3 ,将反转后的数组变成字符串。
     4 ,只要将或反转的部分的开始和结束位置作为参数传递即可。
//===================================================================
3 ,获取一个字符串在另一个字符串中出现的次数。
     "abkkcdkkefkkskk"
     思路:
     1 ,定义个计数器。
     2 ,获取kk第一次出现的位置。
     3 ,从第一次出现位置后剩余的字符串中继续获取kk出现的位置。
         每获取一次就计数一次。
     4 ,当获取不到时,计数完成。
//===================================================================
4 ,获取两个字符串中最大相同子串。第一个动作:将短的那个串进行长度一次递减的子串打印。
     "abcwerthelloyuiodef"
     "cvhellobnm"
     思路:
         1 ,将短的那个子串按照长度递减的方式获取到。
         2 ,将每获取到的子串去长串中判断是否包含,
             如果包含,已经找到!。
//===================================================================
对字符串中字符进行自然顺序排序。
思路:
1 ,字符串变成字符数组。
2 ,对数组排序,选择,冒泡,Arrays.sort();
3 ,将排序后的数组变成字符串。
"vcz1bdAa+cs" -->abccdsvz
//===================================================================
作业:
"12 0 99 -7 30 4 100 13"
要求对字符串中的数值进行排序。生成一个数值从小到大新字符串。
 
"-7 0 4 12 13 30 99 100"
//===================================================================
4. StringBuffer-----子符串缓冲区java.lang.StringBuffer

是一个容器
特点:
1,长度是可变化的。数组也是容器,但长度固定
2,可以 直接操作多个数据类型。
3,最终会通过toString方法变成字符串。

是容器就可以对数据进行操作: CRUD
C-create--U-update--R-read--D-delete;
1,存储。
 StringBuffer  append():将指定数据作为参数添加到已有数据结尾处。
 StringBuffer  insert(index,数据):可以将数据插入到指定index位置。
1
2
3
4
5
6
7
8
StringBuffer sb =  new  StringBuffer();
StringBuffer sb1 = sb.append( 34 );
sop( "sb==sb1:" +(sb==sb1)); //true,脸盆原理(蒸馒头发面,加上面,再加上水,面盆没换)
//******************************************
StringBuffer sb =  new  StringBuffer();
sb.append( "abc" ).append( true ).append( 34 ); //方法调用列,对象调用完方法返回的还是对象本身
sop(sb.toString()); //abctrue34
sb.insert( 1 , "qq" ); //aqqctrue34
2,删除。
 StringBuffer  delete(start,end):删除缓冲区中的数据,包含start,不包含end。
 StringBuffer  deleteCharAt(index):删除指定位置的字符。
1
2
3
4
StringBuffer sb  =  new  StringBuffer( "abcde" );
sb.delete( 1 , 3 ); //包含头不包含尾部
sb.delete(0,sb.length());//**清空缓冲区。
sb.deleteCharAt( 2 ); //一个形式sb.delete(2,3);
 
3,获取。
 char charAt(int index)
 int indexOf(String str)
 int lastIndexOf(String str)
 int length()
 String substring(int start, int end) //此方法返回的还是String类型,不是StringBuffer
 
4,修改。
 StringBuffer   replace(start,end,string);
 void   setCharAt(int index, char ch) ;// 这个比较特殊,返回的是空
1
2
3
StringBuffer sb  =  new  StringBuffer( "abcde" );
sb.replace( 1 , 4 , "java" ); //结果ajavae
sb.setCharAt( 2 , 'k' ); //结果abkde
5,反转。
 StringBuffer reverse();// 自己可以写
//练习二:将字符串反转。
     思路:
     1,将字符串变成数组。
     2,对数组反转。
     3,将数组变成字符串。
 
6, 将缓冲区中指定数据存储到指定字符数组中。
 void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
1
2
3
StringBuilder sb =  new  StringBuilder( "abcdef" );
char [] chs =  new  char [ 6 ];
sb.getChars( 1 , 4 ,chs, 1 );/从 1 4 的字符串存到chs中去,从chs的 1 角标开始的



5,StringBuilder
JDK1.5 版本之后出现了StringBuilder.
StringBuffer是线程同步.<------- (安全的,因为有锁)
StringBuilder是线程不同步。

单线程StringBuilder效率高;
以后开发,建议使用StringBuilder,对于多线程,可以自己加锁

         将  StringBuilder 的实例用于多个线程是不安全的。如果需要这样的同步,则建议使用  StringBuffer

***********************************************************************************************
***********************************************************************************************
java的所有升级大体围绕这三个因素:
1,提高效率。
2,简化书写。
3,提高安全性。




6,基本数据类型对象包装类
封装成类后的一些属性值:
1
2
//整数类型的最大值。
sop( "int max :" +Integer.MAX_VALUE);//MIX_VALUE
byte
Byte
short
short
int
Integer
long
Long
float
Float
double
Double
char
Character
boolean
Boolean
6.1.基本数据类型转成字符串
1.1,String str = 基本数据类型+“”;
1.2 ,Integer.toString( 34 ); //将整数34变成“34"
1.3,String.valueOf(3);//特殊:字符串和字节数组在转换过程中,是可以指定编码表的。
********************************************************************
6.2.字符串转成基本数组类型
1
2
3
4
5
int  a = Integer.parseInt( "123" );
Integer i = new Integer("123");
int num = i.intValue(); //先包装成对象,在调用方法转换
double  b = Double.parseDouble( "12.23" );
boolean  b = Boolean.parseBoolean( "true" );
       对于Char型本身就是String的组成单位,不用转换课直接使用一些方法
**************************************************************************
6.3十进制转成其他进制
 static String toBinaryString();
  toHexString();
  toOctalString(); 
1
2
3
sop(Integer.toBinaryString( 6 )); //结果110
sop(Integer.toHexString( 60 )); //结果3c
sop(Integer.toOctalString( 60 )); //结果74
***************************************************************
6.4其他进制转成十进制。
 parseInt(string,radix);
1
2
3
4
5
6
7
8
9
10
11
parseInt( "0" 10 ) 返回  0
parseInt( "473" 10 ) 返回  473
parseInt( "-0" 10 ) 返回  0
parseInt( "-FF" 16 ) 返回 - 255
parseInt( "1100110" 2 ) 返回  102
parseInt( "2147483647" 10 ) 返回  2147483647
parseInt( "-2147483648" 10 ) 返回 - 2147483648
parseInt( "2147483648" 10 ) 抛出 NumberFormatException
parseInt( "99" 8 ) 抛出 NumberFormatException
parseInt( "Kona" 10 ) 抛出 NumberFormatException
parseInt( "Kona" 27 ) 返回  411787



7,基本数据类型对象包装类新特性
7.1
1
2
3
4
Integer x =  new  Integer( "123" )
Integer y =  new  Integer( 123 );
System.out.println(x==y); //false
System.out.println(x.equals(y)); //true,重载只比较数值
7.2
1
2
3
4
5
6
7
//Integer x = new Integer(4);
Integer x =  4 ; //4是对象,自动装箱。//new Integer(4)
            //注意:x的值除了为整数,还可以是null,小心空指针异常,是runtime异常会停掉
 
x = x +  2 ; //x+2: x进行自动拆箱。变成成了int类型。和2进行加法运算。
           //再将和进行装箱赋给x。
           //代码如下x = x.intValue() + 2;
7.4********
1
2
3
4
5
6
7
8
Integer m =  128 ;
Integer n =  128 ;
sop( "m==n:" +(m==n)); //结果false
 
Integer a =  127 ;
Integer b =  127 ;
sop( "a==b:" +(a==b)); //结果为true。因为a和b指向了同一个Integer对象。
//因为当数值在byte范围内容,对于新特性,如果该数值已经存在,则不会在开辟新的空间


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值