Java学习12(String、StringBuffer、StringBuilder、Integer)

Java学习12

搞了半天最后还是做项目了,好好加油干吧,争取弄出来我也就安心了

String

  1. Java中随便使用双引号括起来的都是String对象,例如:“abc”、“def”“hello world”
  2. Java中规定,双引号括起来的字符串,不可变
    为啥不可变:
      我看过源代码,String类中有一个byte[]数组,byte数组是用final修饰的,因此数组一旦创建长度不可变,并且被final修饰的引用一旦指向某个对象以后,不可再指向其他对象,所以String不可变!
    那为啥StringBuffer/StringBuilder是可变的?
      我看过源代码,它们内部实际上一个byte[]数组,这个byte[]数组没有被final修饰,它们的初始化容量我记得应该是16,当存满之后会进行扩容,底层调用了数组拷贝的方法,System.arraycopy()…是这样扩容的。所以它们适合于频繁的字符串拼接操作
    在这里插入图片描述

StringBuffer继承的抽象类,里面有一个byte[]数组,长度可变
在这里插入图片描述

  1. JDK当中双引号括起来的字符串,例如“abc”都是直接存储在方法区的“字符串常量池”当中的(因为字符串在是实际的开发中使用的太频繁,为了执行效率,所以把字符串放到了方法区的字符串常量池中)

  2. String s = new String(“xy”); //xy存储在字符串常量池中,在堆中创建了一个String对象,其中存储了xy的内存地址,在栈中创建了变量s,其中保存的是String对象的内存地址
    String s1 = “abc”; s1里面保存的不是“abc”字符串,保存的是“abc”字符串对象的内存地址
    在这里插入图片描述

  3. String s1=“hello”;
    String s2=“hello”;
    System.out.println(s1==s2) //由于hello存储在方法区的字符串常量池中,所以hello对象只有一个,s1和s2中存储的地址是一样
    Stirng对象的比较不能用“==”,应该用String中重写equals方法

垃圾回收器是不会释放常量的

  1. String类中的常用构造方法和方法
public class StringTest {
    public static void main(String[] args) {
        String s1 = "hello";
        String s2 = "hello";
        System.out.println(s1 == s2);   //true

        String s3 = new String("xyz");
        String s4 = new String("xyz");
        System.out.println(s3 == s4);   //false
        System.out.println(s3.equals(s4));  //true
        // 构造方法测试
        byte[] bytes = {97,98,99};
        String s5 = new String(bytes);  //将byte数组转换为字符串
        System.out.println(s5);         //abc
        //String(字节数组,数组元素下标起始位置,长度);将字节数组一部分转换为字符串
        String s6 = new String(bytes,1,2);
        System.out.println(s6);         //bc

        char[] chars= {'a','d','c'};
        String charStr = new String(chars);
        String charStr2 = new String(chars,1,2);
        System.out.println(charStr);    //adc
        System.out.println(charStr2);   //dc


        //方法charAt  找出第几个位置的字符
        char c1 = "abcdef".charAt(2);
        System.out.println(c1);     //c
        //方法compareTo
        int result1 = "abc".compareTo("abc"); //前后一致
        System.out.println(result1);        //0
        int result2 = "abcd".compareTo("abcz"); //前小后大 4-26=-22
        System.out.println(result2);
        int result3 = "abcf".compareTo("abce"); //前大后小
        System.out.println(result3);            //1
        //方法boolean contains(CharSequence s) 判断前面的字符串是否包含后面的字符串
        System.out.println("helloWorld".contains("World"));
        //方法boolean  endsWith(String suffix)  判断字符串是否以后面的字符串结尾
        //方法boolean  equalsIgnoreCase(String anotherString)  忽略大小写比较两个字符串
        //方法byte[]  getBytes()  将字符串转换成byte数组
        byte[] bytes1 = "abcedf".getBytes();
        for(int i = 0;i < bytes1.length;i++)
            System.out.print(bytes1[i]+" ");    //97 98 99 101 100 102
        //int indexOf(String str)  判断某个子字符串第一次出现在当前字符串的索引
        //int lastIndexOf(String str)  判断某个子字符串最后一次出现在当前字符串的索引
        //方法 boolean 	isEmpty() 判断字符串是否为空
        //boolean isBlank() 判断字符串是否都是空格
        //int length()  字符串的长度;判断数组长度是length属性,判断字符串长度是length方法

        //String  replace(CharSequence target, CharSequence replacement)
        //String的父接口就是CharSequence  该方法是替换原有字符串的内容
        String newString = "http://baidu.com".replace("http://","https://");
        System.out.println('\n'+newString);
        //String[] 	split(String regex)   以后面的参数拆分字符串,放在一个String数组中
        System.out.println(newString.split("//"));
        String s = "a.b.c";
        String[] ss = s.split("\\.");
        System.out.println(ss[0]);  //a,注意java中正则要两个\\
        //boolean 	startsWith(String prefix)   判断字符串是否以某个字符串开始
        //String 	substring(int beginIndex)   从参数位置截取字符串
        //String 	substring(int beginIndex, int endIndex)   起始位置包括,结束位置不包括
        System.out.println("http://baidu.com".substring(7,10));     //bai
        //char[] 	toCharArray()  将字符串转换为char数组
        //String 	toLowerCase()   转换为小写
        //String 	toUpperCase()   转换为大写
        //String 	trim()   去除字符串前后空白,中间不能去
        //String中只有一个方法是静态的,不需要new对象,这个方法叫做valueOf
        //作用是将非字符串 转换为 字符串
        String x = String.valueOf(true);
        System.out.println(x);      //true
        String y = String.valueOf(new Customer());
        System.out.println(y);	//这里输出toString中的内容,“我爱学习“
        //到此,println输出的时候,是将所有给的数据转换成字符串再输出

    }
}
class Customer{
    @Override
    public String toString() {
        return "我爱学习";
    }
}

StringBuffer

  在实际开发中,如果需要对字符串频繁拼接,因为java中的字符串是不可变的,每一次拼接都会产生新字符串,这样会占用很大的方法区内存,造成内存空间的浪费
  如果要频繁进行字符串拼接,建议使用StringBuffer
  以后进行字符串的拼接,使用StringBuffer中的append()方法
  append方法在底层进行追加的时候,如果byte数组满了,会自动扩容
  StringBuffer/StringBuilder初始化容量16.
  频繁进行字符串拼接不建议使用“+”

如何优化StringBuffer的性能?
   在创建StringBuffer的时候尽可能给定一个初始化容量。
   最好减少底层数组的扩容次数,预估计一下,给一个大一点的初始化容量
   关键点:给一个合适的初始化容量,可以提高程序的执行效率

StringBuilder

使用StringBuilder也可以进行字符串的拼接
区别:
StringBuffer中的方法都有:synchronized修饰,表示StringBuffer在多线程环境下运行是安全的,
StringBuilder没有synchronized修饰,表示在多线程环境下是非安全的

StringBuffer中有synchronized修饰:
在这里插入图片描述

基础类型对应的8个包装类

8种包装类型属于引用数据类型,父类是Object
为什么要提供8种包装类型?
因为8种数据类型不够用

  基本数据类型                    			  包装类型
     byte                               java.lang.Byte(父类Number)
     short                             java.lang.Short(父类Number)
     int                                java.lang.Integer (父类Number)
     long                              java.lang.Long(父类Number)
     float                             java.lang.Float(父类Number)
     double                         java.lang.Double(父类Number)
     boolean                       java.lang.Boolean(父类Object)
     char                            java.lang.Character(父类Object)

在这里插入图片描述

Integer

在这里插入图片描述

Number是一个抽象类,Number中有intValue、longValue、floatValue…六种拆箱方法
Integer i = new Integer(123); //装箱,将基本数据类型包装成引用数据类型
int x = i.intValue(); //拆箱,将引用数据类型转变为基本数据类型

自动装箱: Integer x = 100;//int自动转换为Integer
自动拆箱: int y = x; // Integer自动转换为int
z=x+1; // 会将x自动转换成基本数据类型进行计算

有了自动拆箱之后,Number中的方法就用不着了!
Java5之后,自动装箱和自动拆箱为了方便编程

特殊情况
java中为了提高程序的执行效率,将 -128到127之间所有的包装对象提前创建好,放到了一个方法区的“整数型常量池”当中,目的是只要这个区间的数据不需要new了,直接从整数型常量池取出来

Integer类加载的时候,会初始化整数型常量池:256个对象 (池就是缓存cache)
缓存优点:效率高
缓存缺点:耗费内存

		Integer x = new Integer(100);   //出现横线表示已经过时了
        Integer y = new Integer("123");  //将字符串转换成int
        //Integer z = new Integer("中国");  //数字格式化异常:NumberFormatException

        System.out.println(x+"  "+y);	//100  123

Integer a = new Integer(“中文”);
//编译没问题,运行报错:java.lang.NumberFormatException

常用方法:static int parseInt(String s);将字符串转换为int
static String toHexString(int i); //将十进制转换为十六进制字符串
static String toOctalString(int i); //将十进制转换为八进制字符串
static String toBinaryString(int i); //将十进制转换为二进制字符串

static Integer valueof(int i); //int–>Integer
static Integer valueof(String s); //String–>Integer

		//see ghost,初学的时候挺奇怪的
        Integer a = 128;
        Integer b = 128;
        //java中为了提高程序的执行效率,将-128到127之间所有的包装对象提前创建好,
        //放到了一个方法区的“整数型常量池”当中,目的是只要这个区间的数据不需要new了,
        //直接从整数型常量池取出来

        //原理:x中保存的对象内存地址和y中保存的对象内存地址是一样的,没有在堆中创建对象
        Integer x = 5;
        Integer y = 5;
        System.out.println(a==b);	//false,128没有自动创建,相当于new Integer(128),
        //在常量池中先创建了128,然后在堆中创建了对象指向了128,而两次堆中创建的对象是不同的
        System.out.println(x==y);

        //static int  parseInt(String s)
        //网页上文本框中输入的100实际上是字符串,后台数据库需要将其转换为数字100
        int retValue = Integer.parseInt("123");		
        System.out.println(retValue+100);		//223

        int i = 100;
        String s = i + "";
        System.out.println(s);		//100

在这里插入图片描述
在这里插入图片描述

已学经典异常

空指针异常:NullPointerException
类型转换异常: ClassCastException
数组下标越界异常:ArrayIndexOutOfBoundException
数字格式化异常:NumberFormatException

special:
int i=100;
String s=i+“”;(将整数转换成字符串)

三种类型转换

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值