JAVASE_13_#JavaAPI_String和StringBuffer

来源:互联网 发布:市场营销如何数据分析 编辑:程序博客网 时间:2024/06/04 07:15
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);/从14的字符串存到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
原创粉丝点击