java笔记(String、StringBuffer、包装类)

一、String

1.概述

java.lang.String 字符串类

底层是一个字符数组,所以他的很多特性就是数组则特性

  1. 字符串与一旦确定,不能修改
  2. 为了提高字符串效率,java虚拟机使用了一种"缓存技术",字符串常量池

创建一个字符串对象的时候,先查看字符串常量池中有没有该字符串对象如果没有就创建一个,如果有就直接指向该对象

有时候字符串类型可以用 == 进行比较,是因为他们的内存地址一样(仅限字面量),数字或字母

如果是new方式创建的,则会在堆内存中创建字符串对象,同时也会在常量中创建该字符串对象

java笔记(String、StringBuffer、包装类)_第1张图片

2.基本使用

//字面量相同,只会创建一个对象  abc(常量池中)
String s11="abc";
String s12="abc";
System.out.println(s11 == s12);//t
System.out.println(s11.equals(s12));//t
//会创建3个对象,分别是:
//s13,s14在堆内存中创建的对象(为了指向常量池的"ab"),以及常量池中的对象"ab"
String s13=new String("ab");
String s14=new String("ab");
System.out.println(s13==s14);//f
System.out.println(s14.equals(s13));
String s15=new String("123");
//如果new的时候只创建堆内存对象,而不向常量池中保存
//当调用intern方法时,就会把s15保存到常量池中
s15.intern();
//s6和s5应该相同
String s16="123";
//结果为false,说明new的时候不仅往内存创建一个对象,还在常量池中创建一个对象
//所以当我们调用intern将常量放入常量池中时 发现池中已有,已不会再加进去
//所以s15指向堆内存 , s16指向常量池
System.out.println(s15==s16);
String s17=new String("q")+new String("w");
//将s17手动放入常量池中
s17.intern();
String s18="qw";
// 因为常量池中没有qw,所以s17被放入常量池中,所以s18指向s17
System.out.println(s17==s18);//true 

3.构造方法

//字面量
String s21="abc";
//new
String s22=new String("abc");
//字节数组
byte[] bytes={97,98,99};
String s23=new String(bytes,0,2);
s23=new String(bytes);
System.out.println(s23);
//字符数组
char[] chars11={'a','b','c'};
// 将c1 从第 0 个开始转换2 个为字符串,
//String a=new String(c1,0,2); 
//相当于 c1 , 0 , c1.length 
String s24=new String(chars11);
System.out.println(s24);//abc

4.常用方法

String str="sfsfsfs";
//char charAt(int index) 获取字符串中对应索引的字符
char c=str.charAt(2);
//boolean endWith(String str) 判断某个字符串是否以指定字符串结尾
System.out.println(str.endsWith("fs"));
System.out.println(str.startsWith("fs"));//开头
//byte[] getBytes():把该字符串转换为字节数组并返回
byte[] bytes21=str.getBytes();
//char[] toCharArray(): 把字符串转换为字符数组
char[] chars21=str.toCharArray();
//int indexOf(String str): 获取指定字符串在该字符串中的索引下标,从左往右查找,如果不存在则返回-1
System.out.println(str.indexOf("s"));
System.out.println(str.indexOf("s",2));//2表示从下标2开始往后找,包括2
//int lastIndexOf(String str): 最后一次出现的索引,找不到返回-1,与indexOf()相反
System.out.println(str.lastIndexOf("s"));
System.out.println(str.lastIndexOf("s",1));//从下标1 开始,从右往左找
//int length(): 返回字符串长度
System.out.println(str.length());
str="gkdfkfhsaffhhfafsjf";
//String replace(String a,String b):替换后返回新的字符串
System.out.println(str.replace("h", "+"));
//repalceAll :支持正则表达式
System.out.println(str.replaceAll("h", "+"));
//String[] split(String str):以特定字符串进行分割,返回字符串数组,支持正则表达式
str="2024-1-15";
String[] strings =str.split("-");
for (int i = 0; i < strings.length; i++) {
	System.out.println(strings[i]);
}
//String substring(int index):截取字符串,获取指定索引开始(包含指定索引)到结束的子字符串
str="abcdef";
System.out.println(str.substring(2));
System.out.println(str.substring(3,5));//左闭右开,包含3,但不包括5
//String toUpperCase():转为大写并返回
System.out.println("GJgJgggJ".toUpperCase());
//String toLowerCase():转为小写并返回
System.out.println("GJgJgggJ".toLowerCase());
//String trim() :删除两边空格并返回,下面三个输出结果并不相同
System.out.println("    h  a lll o  wwwww       ");
System.out.println("    h  a lll o  wwwww       ".trim());
System.out.println("    h  a lll o  wwwww       ".replace(" ", ""));
//比较两个字符串是否相同
System.out.println("aaa".equals("AaA"));
//忽略大小写再比较
System.out.println("aaa".equalsIgnoreCase("AaA"));
//static String valueOf(Object obj): 调用对象(一定要是对象)的toString方法,并对null值进行处理,避免空指针
Object obj=null;
System.out.println(String.valueOf(obj));
//创建对象,StringBuilder是可自动扩展的字符串
StringBuilder sb=new StringBuilder();
//尾部添加
sb.append("a");
sb.append("b").append("c").append("d");
//添加到指定位置
sb.insert(1, "e");
//反转
sb.reverse();
//添加元素个数
System.out.println(sb.length());
//当前容量
System.out.println(sb.capacity());
//转换为String类型
String string=sb.toString();
System.out.println(string);

5.注意

字符串不能频繁做拼接操作,因为字符串一旦确定不能修改

频繁拼接字符串效率较低,并且不利于自动垃圾回收

二、StringBuffer 和 StringBuilder

1.概述

StringBuffer 和 StringBuilder底层都是char数组,只不过该数组可变长,所以当我们需要进行频繁的字符串拼接时,可以使用StringBuffer 和 StringBuilder

1.1.原理:

预先在内存中申请一个空间,足以容纳更多字符

如果预留空间不够了会自动进行扩容

默认初始化长度为16,扩大容量为length*2+2,即((value.length << 1) + 2)

1.2.StringBuffer 和 StringBuilder区别:

StringBuffer:线程安全,在多线程环境下不会出现问题,常用于类中

StringBuilder:非线程安全,在多线程环境下,可能出现问题,常用于方法中

2.基本使用

//创建对象,StringBuilder是可自动扩展的字符串
StringBuilder sb=new StringBuilder();
//尾部添加
sb.append("a");
sb.append("b").append("c").append("d");
//添加到指定位置
sb.insert(1, "e");
//反转
sb.reverse();
//添加元素个数
System.out.println(sb.length());
//当前容量
System.out.println(sb.capacity());
//转换为String类型
String string=sb.toString();
System.out.println(string);

obj自带函数(StringBuilder–>AbstractStringBuilder–>ensureCapacityInternal(newCapacity))

private void ensureCapacityInternal(int minimumCapacity) {
        // overflow-conscious code
        if (minimumCapacity - value.length > 0) {
            value = Arrays.copyOf(value,
                    newCapacity(minimumCapacity));
        }
    }

private int newCapacity(int minCapacity) {
        // overflow-conscious code
        int newCapacity = (value.length << 1) + 2;
        if (newCapacity - minCapacity < 0) {
            newCapacity = minCapacity;
        }
        return (newCapacity <= 0 || MAX_ARRAY_SIZE - newCapacity < 0)
            ? hugeCapacity(minCapacity)
            : newCapacity;
    }

三、包装类

1.概述

为了对基本数据类型进行更多的操作,最方便的方式就是将其封装成对象,因为在对象描述中就可以定义更多的属性和行为对该基本数据类型进行更多操作。我们不需要自己去对基本数据类型进行封装,JDK已经为我们封装好了

  1. 装箱就是自动将基本数据类型转换为包装器类型
  2. 拆箱就是自动将包装器类型装转换为基本数据类型

java笔记(String、StringBuffer、包装类)_第2张图片

2.使用

//基本类型
byte b31=1;
//包装类类型,大部分是首字母大写,除了int 和char
Byte b32=new Byte(b31);
Byte b33=new Byte(b31);
System.out.println(b32.equals(b33));
boolean flag31=true;
Boolean flag32=new Boolean(flag31);
m31(b32);
//Object可以接收任意类型的数据
public static void m31(Object obj){
	System.out.println(obj);
}

3.Integer

3.1.基本使用

//最大值
System.out.println(Integer.MAX_VALUE);
//最小值
System.out.println(Integer.MIN_VALUE);
System.out.println(Long.MAX_VALUE);
System.out.println(Byte.MAX_VALUE);
//创建对象
Integer i51=new Integer(1);
//还可以传入纯数字的字符串
Integer i52=new Integer("666");
//必须传入纯数字,否则报错
//java.lang.NumberFormatException: For input string: "666a"
Double i53=new Double("66.6");//也只能传数字
Character i54=new Character('a');//只可以传单字符

3.2.相互转换

//int ->Integer
Integer i81=Integer.valueOf(6);
//Integer -->int 
int i82=i51.intValue();
//String -->Integer
Integer i83=Integer.valueOf("66");
//integer -->String 
String s81=i83.toString();
//int --String 
String s82=123+"";
//String -->int 
int i84=Integer.parseInt("66");

3.3.常用方法

//创建对象,可以把int封装为Integer 类型
Integer i71=new Integer(66);
//通过intValue把包装类转换为基本类型
int i72=i71.intValue();
//重要:static int parseInt(String s):把纯数字的字符串转换为int类型
i72 = Integer.parseInt("666");
double score = Double.parseDouble("66.6");
//static String toBinaryString(int value):转换为字符串类的二进制表示法
System.out.println(Integer.toBinaryString(15));
//转十六进制
System.out.println(Integer.toHexString(15));
//转八进制
System.out.println(Integer.toOctalString(15));
//重要 static Integer valueOf(int value):把int类型转换为Integer类型
Integer i74=Integer.valueOf(666);
System.out.println(i74);
Integer i75=Integer.valueOf("66");//也不可以是abc字符
System.out.println(i75);
//不可以是小数,报错 格式错误
//Integer i76=Integer.valueOf("66.6");

3.4.自动装箱和自动拆箱

装箱:基本类型到引用类型

拆箱:引用类型到基本类型

自1.5开始,引入了自动装箱和自动拆箱

//1.5之前的装箱
Integer i61=new Integer(6);
i61=Integer.valueOf(6);
//1.5及以后的装箱
Integer i62=12;//会自动编译为Integer i61=Integer.valueOf(6);
//1.5之前的拆箱
int i63=i62.intValue();
//1.5及以后的拆箱
int i64=i62;
//此时 66为int类型,会自动装箱为integer类型,然后再向上转型发生多态
m61(66);
public static void m61(Object obj){
}

3.5.深入整形常量池

IntegerCache.cache是整形常量池,是个数组,保存了256个integer对象,分别是-128~127

当我们进行自动装箱或手动调用Integer.valueOf()方法时,会先判断是否符合整形常量池

如果符合范围,则直接在整形常量池中把提前创建好的对象引用,赋值即可,不用再次创建

//直接在堆内存中创建对象
Integer i41=new Integer(1);
Integer i42=new Integer(1);
System.out.println(i41==i42);
System.out.println(i41.equals(i42));
//自动装箱,会转型为Integer.valueOf()
//valueOf中进行了整形常量池操作
//如果值在 -128~127 之间,则不需要创建对象,否则,会在堆内存创建对象(new Integer())
Integer i43=2;//相当于 i43=Integer.valueOf(2)
Integer i44=2;
System.out.println(i43==i44);//true
Integer i45=666;
Integer i46=666;
System.out.println(i45==i46);//false

Integer–>valueOf

 public static Integer valueOf(int i) {
     //先判断时候在-128~127中
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            //在就返回已创建好的对象引用
            return IntegerCache.cache[i + (-IntegerCache.low)];
     	//否则就创建新的堆内存对象
        return new Integer(i);
    }

你可能感兴趣的:(java,笔记)