八大wrapper类
八种基本数据类型对应的引用类型–包装类
里面有类的方法,比较方便。
继承体系图:
包装类与基本数据的转换
1)JDK5之前的手动装箱和拆箱方式
2)JDK5之后自动装箱拆箱
3)自动装箱底层调用的方法是valueOf,Integer.valueOf();
//手动装箱 数据类型--包装类型
int i = 1;
Integer i1 = new Integer(i);
Integer i2 = Integer.valueOf(i);
//手动拆箱 包装类型--数据类型
Integer j = new Integer(2);
int j1 = j.intValue();
//自动装拆
int m = 1;
Integer m1 = m;
Integer n = new Integer(2);
int n1 = n;
随机细节
Object obj = true ? new Integer(1) : new Double(2.0);
//三元运算符是一个整体,输出1.0
包装类的转换
//Integer ---> String
Integer i =1;
//1.
String s1 = i + "";
//2
String s2 = i.toString();
//3
String s3 = String.valueOf(i);
//String ---> Integer
System.out.println("s1"+Integer.valueOf(s1));
System.out.println("s2"+Integer.parseInt(s2));
System.out.println("s3"+new Integer(s3));
包装类常用的方法
Integer例题细节
Integer i = new Integer(1);
Integer j = new Integer(1);
System.out.println(i == j); //不是同一个对象 FALSE
Integer m = 1; //Integer.valueOf(1);
Integer n = 1;//Integer.valueOf(1);
System.out.println( m == n); //直接返回 true (Integer.catch数组)
Integer x = 128;
Integer y = 128;
System.out.println(x == y); // new的 false
Integer a1 = 127;
int a2 = 127;
System.out.println(a1 == a2); //true 只要有基本数据类型,判断的是值相等
/*
Integer.valueOf 源码
int i 的范围 -128 ~ 127 直接返回 否则就 new
*/
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
String类
== 字符串的字符使用Unicode字符编码,一个字符(不区分字母还是汉字)占2个字节。==
String 是final类 不能被继承
String 中有 private final char value[];用于存放字符串内容(value一旦赋值就不能修改,是value的地址不可修改,不能指向新的地址)
即:
final char[] v = {'a','b','c'};
char[] v2 = {'c','d','e'};
v[0] ='n'; //可修改内容
v=v2; //加上final v不能指向新的地址,去掉可以
继承关系
String创建
1.直接赋值 String s1 = “hsp”;
2.调用构造器 String s2 = new string(“hsp”);
方式一:先从常量池看看是否有"hsp"数据空间,有直接指向,没有则重新创建,然后指向。最终的指向是常量池的空间地址。
方式二:先在堆中创建空间,里面维护了value属性,指向常量池的"hsp"空间。如果常量池没有用"hsp",重新创建,如果有,直接通过value指向,最终指向是堆中的空间地址。
例题分析
String a = "abc";
String b = "abc";
System.out.println(a.equals(b));//String.equals 重写方法 比较内容 T
System.out.println(a == b ); //都是指向的常量池的地址 T
b = "cdf"; //b指向“cdf” 常量池的地址去了
System.out.println(a); //abc
System.out.println(b);//cdf
String a = "abc"; //常量池
String b = new String("abc"); //堆中对象 value指向常量池
System.out.println(a.equals(b)); //T
System.out.println(a == b );//F
System.out.println(a == b .intern());//T b.
System.out.println(b == b.intern());//F
System.out.println(b.hashCode()== b.intern().hashCode()); //T 都是“abc”的hashcode
/*
intern();看看常量池有没有“abc”,有得到常量池“abc”的地址,没有会把“abc”添加到常量池
*/
Person person1 = new Person();
person1.name = "jack";
Person person2 = new Person();
person2.name = "jack";
System.out.println(person1.name.equals(person2.name)); //true
System.out.println(person1.name == person2.name);//true
System.out.println(person1.name == "jack");//true
Person person1 = new Person();
person1.name = new String("jack");
Person person2 = new Person();
person2.name = new String("jack");
System.out.println(person1.name.equals(person2.name)); //true
System.out.println(person1.name == person2.name);//false
//创建了2个字符串常量对象
String s1 = "123";
s1 = "456";
String s = "hello" + "world";
//编译器会优化 等价 String s =“helloworld” 创建1个对象
String s1 = "hello";
String s2 = "world";
String s3 = s1 + s2; //创建了3个对象
System.out.println(s3 == "helloworld"); //false
// StringBuilder --> StringBuilder append("hello")--->StringBuilder append("world") --->toString()
//--->s3 指向堆中的对象(String)value[]指向"helloworld"
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
@Override
public String toString() {
// Create a copy, don't share the array
return new String(value, 0, count);
}
//========================================================
String s1 = "hello";
String s2 = "world";
String s3 = s1 + s2;
String s4 = s1 + "world";
String s5 = "hello" + s2;
System.out.println(s3 == "helloworld"); //F
System.out.println(s4 == "helloworld");//F
System.out.println(s3 == s4);//F
System.out.println(s4 == s5);//F
System.out.println(s3.hashCode() == s4.hashCode());//T
System.out.println(s5.hashCode() == s4.hashCode());//T
String s = “hello” + “world”; //常量相加,看的是池
String s3 = s1 + s2; //变量相加,是在堆中
例题分析
public static void main(String[] args) {
/*分析
* 1.栈中main方法 ,栈中test地址指向堆中对象
* 堆中的test包含字符串str(new String 是value[]指向常量池的"hello"地址) String -->value--->"hello"
* test包含的数组 (指向一个堆中的地址 有'j','a','v','a')
* 2.test,change();方法 在栈中开辟空间执行change方法
* 3.change()方法传参,先传String参数,String为指向常量的地址,调用方法str = "hi" 指向了常量池的 “hi” (不是new的所以没有指向堆中) String--->"hi"
* 传递的ch[]指向的堆中的ch[],修改了堆中的也跟着改变为'h','a','v','a'
*4.change栈销毁
* 5.输出栈的test.str 依旧是堆中的String 是value[]指向常量池的"hello"地址
* 6.输出test.ch 指向堆中的'h','a','v','a'
* */
Test test = new Test();
test.change(test.str, test.ch);
System.out.println(test.str ); //hello
System.out.println(test.ch); //hava
}
}
class Test{
String str = new String("hello");
final char[] ch = {'j','a','v','a'};
public void change(String str,char ch[]){
str = "hi";
ch[0] = 'h';
}
String常用方法
.equals //区分大小写,判断内容是否相等
.equalsIgnoreCase //忽略大小写判断内容是否相等
.length //字符串长度
.indexOf //字符第一次出现的索引,找不到-1
.lastIndexOf //字符最后一次出现的索引
.subString //截取指定范围的的子串
.trim //去前后空格
.charAt //获取某索引的字符。不能用Str[index]
.toUpperCase //转换成大写
.toLowerCase //转化成小写
.concat //拼接
.replace //代替字符串的字符(返回的结果才是替换的)
.split //分割字符串
.toCharArray //转换成字符数组
.compareTo //比较2字符串大小,前者大返回正数,后者大返回负数,相等返回0
.format //格式字符串 %s字符串 %c字符 %d整型 %2.f浮点型
//String format =“%s %c %d ”;
//String s =String.format(format,字符串,字符,整型);
StringBuffer
public final class StringBuffer
extends AbstractStringBuilder
implements java.io.Serializable, CharSequence{}
//父类有属性 char[] value 不是final 存放字符串内容 存放在堆中 不能被继承
String 与StringBuffer
1)String保存的是字符串常量,里面的值不能更改,每次更新实际上是更改地址
2)StringBuffer 保存的是常量,里面的值可以修改,每次更新是更新内容,不用更新地址
//1 char[16]
new StringBuffer();
//2.指定大小
new StringBuffer(int);
//3.字符串长度+16
new StringBuffer("字符串");
String 与StringBuff的转换
/*
* String---> StringBuffer
* */
String str = "hello";
//1.返回的才是StringBuffer对象,对str本身没有影响
StringBuffer stringBuffer = new StringBuffer(str);
//2.使用append
StringBuffer stringBuffer1 = new StringBuffer();
stringBuffer1 = stringBuffer1.append(str);
/*
* StringBuffer---> String
* */
StringBuffer buffer = new StringBuffer("hello");
//1.toString
String string = buffer.toString();
//2.
String string1 = new String(buffer);
StringBuffer常用的方法
1.append 增
2.delete(start,end) 删 [start,end)
3.replace(start,end,string) 改 [start,end)
4.indexOf 查
5.insert 插
6.length
例题
String str = null;
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append(str); //null 变成 “null”
System.out.println(stringBuffer.length()); //4
System.out.println(stringBuffer); //null
StringBuffer stringBuffer1 = new StringBuffer(str); //异常
System.out.println(stringBuffer1);
StringBuilder
可变字符序列,提供与StringBuffer兼容的API,但不保证同步(不是线程安全)
单线程优先使用Stringbuilder 比StringBuffer快,主要append insert
String Stringbuilder StringBuffer
String随机练习:
字符串指定的部分进行反转,"abcdef"转换成“aedcbf”
public static void main(String[] args) {
/*
* 字符串指定的部分进行反转,"abcdef"转换成“aedcbf”
* */
String s ="abcdef";
System.out.println(reverse(s,1,4));
System.out.println(reverse01(s,1,4));
System.out.println(reverse02(s,1,4));
System.out.println(reverse(s,0,5));
System.out.println(reverse01(s,0,5));
System.out.println(reverse02(s,0,5));
}
public static String reverse(String str,int start,int end){ //数组交换
if(null== str ||start<0 || end > str.length()-1 ){
return "error";
}
char[] chars = str.toCharArray();
char temp = ' ';
for (int i = start,j = end;i < j;i ++,j --){
temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
}
return new String(chars);
}
public static String reverse01(String str,int start,int end){
if(null== str || start<0 || end > str.length()-1){
return "error";
}
String startStr = str.substring(0,start);
String endStr = str.substring(end+1, str.length());
StringBuilder stringBuilder = new StringBuilder(str.substring(start,end+1));
return startStr+ stringBuilder.reverse() + endStr;
}
public static String reverse02(String str,int start,int end){
if(null== str || start<0 || end > str.length()-1){
return "error";
}
StringBuilder startStr = new StringBuilder(str.substring(0,start));
StringBuilder endStr = new StringBuilder(str.substring(end+1, str.length()));
StringBuilder stringBuilder = new StringBuilder(str.substring(start,end+1));
return startStr.append(stringBuilder.reverse()).append(endStr).toString();
}