Java学习12(String)

Posted Zephyr丶J

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java学习12(String)相关的知识,希望对你有一定的参考价值。

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()...是这样扩容的。所以它们适合于频繁的字符串拼接操作
3.JDK当中双引号括起来的字符串,例如“abc”都是直接存储在方法区的“字符串常量池”当中的(因为字符串在是实际的开发中使用的太频繁,为了执行效率,所以把字符串放到了方法区的字符串常量池中)
4.String s = new String("xy");  //xy存储在字符串常量池中,在堆中创建了一个String对象,其中存储了xy的内存地址,在栈中创建了变量s,其中保存的是String对象的内存地址
    String s1 = “abc”;  s1里面保存的不是“abc”字符串,保存的是“abc”字符串对象的内存地址

在这里插入图片描述

5.	String s1="hello";
    String s2="hello";
    System.out.println(s1==s2)  //由于hello存储在方法区的字符串常量池中,所以hello对象只有一个,s1和s2中存储的地址是一样
    Stirng对象的比较不能用“==”,应该用String中重写equals方法
    
    (****)垃圾回收器是不会释放常量的
    
6.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() 判断字符串是否为空
        //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("//"));
        //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);
        //到此,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修饰,表示在多线程环境下是非安全的

基础类型对应的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);
        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+“”;(将整数转换成字符串)

三种类型转换

在这里插入图片描述

以上是关于Java学习12(String)的主要内容,如果未能解决你的问题,请参考以下文章

Java程序片段

201621123037 《Java程序设计》第9周学习总结

java.lang.NullPointerException: Attempt to invoke virtual method ‘int android.database.sqlite异常(代码片段

Failed to convert property value of type ‘java.lang.String‘ to required type ‘int‘ for property(代码片段

Jsp获取Java的重定向赋值(String)

学号:201521123116 《java程序设计》第八周学习总结