包装类
包装类的基本使用
Java提供了8中数据类型对应的包装类
基本数据类型 | 包装类 |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
float | Float |
double | Double |
boolean | Boolean |
char | Character |
包装类与基本数据类型的互相转换
public class Demo01 {
//TODO string转其他基本数据类型---->pasexxxx()方法
public static void main(String[] args) {
String str1 = "123";
int num = Integer.parseInt(str1);
System.out.println(num);
String str2 = "true";
boolean b = Boolean.parseBoolean(str2);
System.out.println(b);
}
}
public class Demo02 {
//TODO 基本数据类型----->String,调用string重载的valueOf()
public static void main(String[] args) {
int num1 = 10;
String str1 = num1 + "";
float f1 = 31.4f;
String str2 = String.valueOf(f1);
System.out.println(str2);
Double d1 = new Double(3);
String str3 = String.valueOf(d1);
System.out.println(str3 );
}
}
//TODO 自动装箱与自动拆箱
public static void main(String[] args) {
//自动装箱: 基本数据类型 ---》包装类
int num1 = 10;
Integer inte1 = num1; //自动装箱
System.out.println(inte1);
boolean b1 = true;
Boolean b2 = b1; //自动装箱
System.out.println(b2);
//包装类 --》String
Integer inte2 = 11;
String s = inte2.toString();
System.out.println(s);
//自动拆箱: 包装类----》基本数据类型
int num3 = inte1;
System.out.println(num3);
}
//TODO 包装类---》基本数据类型 :调用包装类的方法:xxxValue()
public static void main(String[] args) {
Integer int1 = new Integer(12);
int i1 = int1.intValue();
System.out.println(i1 + 1);
Float f1 = new Float(31.4);
float f2 = f1.floatValue();
System.out.println(f2 + 1);
}
//TODO 基本数据类型 ---》 包装类,调用包装类的构造器
public static void main(String[] args) {
int num1 = 10;
Integer int1 = new Integer(num1);
System.out.println(int1);
Float f1 = new Float(12.3f);
System.out.println(f1);
Boolean b = new Boolean(true);
System.out.println(b);
}
public static void main(String[] args) {
//包装类--》String
int num1 = 10;
Integer int1 = new Integer(num1);
String str1 = int1.toString();//拆箱返回的是字符串
System.out.println(str1);
Float f1 = new Float(12.3f);
String str2 = f1.toString();
System.out.println(str2);
Boolean b = new Boolean(true);
String str3 = b.toString();
System.out.println(str3);
//String ---->包装类
Boolean aTrue = new Boolean("true");
}
装箱与拆箱
基本数据类型的包装类是为了基本数据类型转为对象提供的,那么对于基本数据类型和包装类之间有处理关系:
- 数据装箱:基本数据类型------->包装类,一般利用构造方法
- 数据拆箱:从包装类------->基本数据类型 调用xxxValue()
public static void main(String[] args) {
Integer obj1 = new Integer(10);//装箱
int num1 = obj1.intValue();//拆箱
System.out.println(num1);
//自动装箱与拆箱
Integer obj2 = 10; //自动装箱
int num = obj2; //自动拆箱
obj2++;
System.out.println(num * obj2);
// Object 接收 基本数据类型
Object obj3 = 19.3;//double 自动转型为 Double,向上转型为Object
double num3 = (Double) obj3;
System.out.println(num3);
}
对于包装类的判断上:
public class Demo02 {
public static void main(String[] args) {
Integer x1 = 99;
Integer y1 = 99;
System.out.println(x1 == y1);
Integer x2 = 127;
Integer y2 = 99;
System.out.println(x2 == y2);
Integer x3 = -129;
Integer y3 = -129;
System.out.println(x3 == y3);//flase,因为超过了范围,所以new 了新的对象
System.out.println(x3.equals(y3));//true
// 因为包装类重写了equals()方法,调用了xxxvalue()方法,进行了拆箱,最终是这是两个基本数据类型的比较(看源码)
Integer x4 = 127;
Integer y4 = new Integer(127);
System.out.println(x4 == y4); //false
System.out.println(x4.equals(y4)); //true
int x5 = 99;
Integer y5 = 99;
System.out.println(x5 == y5);
int x6 = 128;
Integer y6 = 128;
System.out.println(x6 == y6);
}
String类
字符串相关的类
字符串
- 字符串,使用“ ”引用起来
- String声明为final,不可以被继承
- String实现了serializable接口,表示字符串是支持序列化的
- String实现了comparable接口:表示可以比较大小
- String内部定义了final char【】value 用于存储字符串数据
String类不可变性
- String: 代表不可变的字符串序列,简称不可变性
体现:
a.当对字符串重新赋值时,需要重写指定内存区赋值,不能使用原有的value进行赋值
b.对现有的字符串进行连接操作时,也需要重新制定内存区域赋值,不能使用原有的value赋值
c.当调用String的replace()方法修改字符或者字符,也需要重新指定内存区域赋值,不能使用原有的value进行赋值
public class StringTest {
public static void main(String[] args) {
String str1 = "abc";
String str2 = "abc";
str1 = "hello";
System.out.println(str1==str2);//比较的是地址值
System.out.println(str1);
System.out.println(str2);
System.out.println("=================");
String str3 = "abc";
str3 += "def";
System.out.println(str3);
System.out.println("=================");
String str4 = "abc";
String str5 = str4.replace('a','e');
System.out.println(str4);//abc
System.out.println(str5);//ebc
}
}
String不同实例化方式的对比
String 对象的创建
String str1 = "hello";
//this.value = new char[0]
String str2 = new String();
//this.value = original.value;
String str3 = new String(String original);
//this.value = Arrays.copyOf(value, value.length);
String str4 = new String(char value[]);
String str4 = new String(char value[],int startIndex, int count);
String str1 = “abc”; 与 String str2 = new String(“abc”);的区别
- 字符串常量存储在字符串常量池里面,目的是共享
- 字符串对象存储在堆中
String的实例化方式
方式一: 通过字面量定义的方式
方式二: 通过 构造器的方式
public static void main(String[] args) {
//通过字面量的方式定义,存储在 字符串常量池里面
String str1 = "eagel";
String str2 = "eagel";
//通过构造器的方式:存储在堆里面
String str3 = new String("eagel");
String str4 = new String("eagel");
System.out.println(str1 == str2);
System.out.println(str1 == str3);
System.out.println(str1 == str4);
System.out.println(str3 == str4);
}
public static void main(String[] args) {
//通过字面量的方式定义,存储在 字符串常量池里面
String str1 = "eagel";
String str2 = "eagel";
//通过构造器的方式:存储在堆里面
String str3 = new String("eagel");
String str4 = new String("eagel");
System.out.println(str1 == str2);
System.out.println(str1 == str3);
System.out.println(str1 == str4);
System.out.println(str3 == str4);
System.out.println("=======================");
Person person1 = new Person("herb", 18);
Person person2 = new Person("herb", 18);
System.out.println(person1.name.equals(person2.name));
//true
System.out.println(person1.name == person2.name);
//true
person2.name = "eagle";
System.out.println(person2.name);
}
面试题:通过String str1 = new String(“herb”);方式 创建对象,请问在内存中创建了多少个对象?
两个:一个是堆空间中对象,另一个是char[]数组
String 不同的拼接操作对比
- 常量与常量的拼接结果在常量池,且常量池中不会存在相同的内容
- 只要其中一个是变量,结果就在堆中
- 如果拼接的结果调用intern()方法,返回值就在常量池中。
public class Demo02 {
public static void main(String[] args) {
String str1 = "JavaEE";
String str2 = "eagle";
String str3 = "JavaEEeagle";
String str4 = "JavaEE" + "eagle";
String str5 = str1 + "eagle";
String str6 = "JavaEE" + str2;
String str7 = str1 + str2;
System.out.println(str3 == str4);//true
System.out.println(str3 == str5);//false
System.out.println(str3 == str6);//false
System.out.println(str5 == str6);//false
System.out.println(str3 == str7); //false
System.out.println(str5 == str7);//false
System.out.println(str6 == str7);//false
}
}
public static void main(String[] args) {
String str1 = "JavaEE";
String str2 = "eagle";
String str3 = str2 + "eagle";//结果在堆中
System.out.println(str1 == str3); //false
final String str4 = "JavaEE";
String str5 = str4 + "eagle";
System.out.println(str1 == str4);//true
}
陷阱
String str1 = “a” 在常量池
str1 = str1 + “b”
说明,实际上原来的 "a"字符串对象已经丢弃,现在在对空间产生了一个字符串 str1 + “b”,如果多次执行这些改变字符串内容的操作,会导致大量副本字符串对象存留在内存中。
String str2 = “ab” 在常量池
String str3 = “a” + “b” 在常量池(指向str2)
String str4 = str1.intern(); //引用str2 (字符串常量池)
说明:堆空间的str1 对象在调用 intern()之后,会将常量池中已经存在的 "ab"字符串赋值给 str4
public class Demo04 {
public void change(String str1, char chats[]) {
str1= "hello";
chats[0] = 'a';
}
public static void main(String[] args) {
String str = new String("herb");
char[] chars = {'e', 'a', 'g', 'l', 'e'};
Demo04 test = new Demo04();
test.change(str, chars);
System.out.println(str); //字符串的不可变性
System.out.println(chars);
}
}
String常用方法
int length() :返回字符串的长度
char charAt(int index):返回某索引处的字符
boolean isEmpty():判断字符串是否为空
String toLowerCase():将String 中的所有字符转换为小写
String toUpperCase() : 将String中的所有字符转换为大写
String trim():返回字符串的副本,忽略 前面的空白和尾部的空白
boolean equals(Object anObject):比较字符串的内容是否相等
boolean equalsIgnoreCase(String anotherString):比较字符串的内容是否相等,忽略大小写
String concat(String str):将字符串拼接到此字符串的结尾,等价与”+“
int compareTo(String anotherString):比较两个字符串的大小
String substring(int beginIndex):返回一个新的字符串,字符串从beginIndex开始截取到最后一个字符
String substring(int beginIndex, int endIndex):返回一个新的字符串,字符串从beginIndex开始截取到endIndex(不包含)的一个子字符串
public static void main(String[] args) {
String str1 = "helloworld";
System.out.println(str1.length());
System.out.println(str1.charAt(0));
System.out.println(str1.charAt(3));
System.out.println(str1.isEmpty());
String str2 = str1.toUpperCase();
System.out.println(str1);
System.out.println(str2);
String str3 = " herb eag le ";
String str4 = str3.trim();
System.out.println(str3);
System.out.println(str4);
}
public static void main(String[] args) {
String str1 = "HELLOWORLD";
String str2 = "helloworld";
System.out.println(str1.equals(str2));//false
System.out.println(str1.equalsIgnoreCase(str2));//true
String str3 = "aaa";
String str4 = str3.concat("herb");
System.out.println(str4);
String str5 = "aaa";
String str6 = new String("bbb");
System.out.println(str5.compareTo(str6));//-1
String str7 = "你好呀,herb";
String str8 = str7.substring(2);
System.out.println(str7);
System.out.println(str8);
String str9 = str7.substring(2, 4);
//[2,4)-->【2,3】
System.out.println(str9);
}
- boolean endsWith(String suffix):测试此字符串是否以指定的后缀结束
- boolean startsWith(String prefix):测试此字符串是否以指定的前缀开始
- boolean startsWith(String prefix, int toffset):测试此字符串从指定索引开始的子字符串是否以指定前缀开始
- boolean contains(CharSequence s):判断字符串是否包含指定的字符穿
- int indexOf(String str):返回指定字符串在此字符串中第一次出现的所用
- int indexOf(String str, int fromIndex):从指定的索引开始,返回指定字符串在此字符串中第一次出现的索引。
- int lastIndexOf(String str):返回指定字符串在此字符串中最右边出现的索引(最后一次出现)
- int lastIndexOf(String str, int fromIndex):从指定的索引反向搜索,返回指定字符串最后一次出现处的索引
indexOf 和 lastIndexOf 方法如果找不到,返回-1
public static void main(String[] args) {
String str1 = “helloworld”;
boolean rld = str1.endsWith(“rld”);
System.out.println(rld);
boolean hel = str1.startsWith("hel");
System.out.println(hel);
boolean ll = str1.startsWith("ll", 2);
System.out.println(ll);
System.out.println(str1.contains("wor"));
System.out.println(str1.indexOf("ll"));
System.out.println(str1.indexOf("ll",4));
System.out.println(str1.lastIndexOf("rl"));
System.out.println(str1.lastIndexOf("ll", 4));
}
替换:
- String replace(char oldChar, char newChar):返回一个新的字符串,它是通过 newChar 替换 字符串中所有的oldChar
- String replace(CharSequence target, CharSequence replacement):使用指定的字面值替换此字符串所有匹配字面值目标序列的子字符串
- String replaceAll(String regex, String replacement):使用给定 replacement 替换此字符串所有满足正则表达式的子字符串。
- String replaceFirst(String regex, String replacement):使用 replacement 替换此字符串满足正则表达式的第一个子字符串。
匹配:
boolean matches(String regex):字符串是否 匹配 给定的正则表达式
- String[] split(String regex):根据给定的正则表达式 的匹配 来拆分字符串
- String[] split(String regex, int limit):根据给定的正则表达式 来拆分字符串,但是最多不超过limit个,如果超过了,剩下的全都放到最后一个元素中。
public static void main(String[] args) {
String str1 = "herb eagle";
String replace = str1.replace('h', 'a');
System.out.println(replace);
String replace1 = str1.replace("erb", "avc");
System.out.println(replace1);
}
String与char[]之间的转换
String —>char[]:调用 String 的 toCharArray()
char[]—>String : 调用String的构造器
public static void main(String[] args) {
String str1 = "123abc";
char[] chars = str1.toCharArray();
for (int i = 0; i < str1.length(); i++) {
System.out.print(chars[i]);
}
System.out.println();
char[] chars1 = {'h', 'e', 'r', 'b', 'e', 'a','g', 'l', 'e'};
String s = new String(chars1);
System.out.println(s);
}
String与byte[]之间的转换
String —>byte[]:调用 String的 getBytes()
byte[]----> String:调用String的构造器
编码: 字符串—>字节(二进制)
解码:字节(二进制)—>字符串
public static void main(String[] args) throws UnsupportedEncodingException {
String str1 = "aa123你好";
byte[] bytes = str1.getBytes();
System.out.println(Arrays.toString(bytes));
byte[] bytes1 = str1.getBytes("gbk");
System.out.println(Arrays.toString(bytes1));
String str2 = new String(bytes);
System.out.println(str2);
String str3 = new String(bytes1);//出现乱码
System.out.println(str3);//编码集和解码集不一致!
String gbk = new String(bytes1, "gbk");
System.out.println(gbk);
}
String 算法
- 模拟一个 trim方法,去除字符串两端的空格
public class MyTrimTest {
public static String MyTrim(String str) {
if (str != null) {
int start = 0;//头指针
int end = str.length() - 1;//尾指针
while ((start < end) && (str.charAt(start) == ' ')) {
start++;
}
while ((start < end) && (str.charAt(end) == ' ')) {
end--;
}
return str.substring(start, end + 1);
}
return null;
}
public static void main(String[] args) {
String str = " abc ";
String s = MyTrim(str);
System.out.println(s);
}
}
反转字符串,指定部分反转
abcde —> edcba
public class ReverseTest {
//TODO char[] 数组
public static String reverse(String str, int startIndex, int endIndex) {
if (str != null && str.length() != 0) {
char[] chars = str.toCharArray();
for (int i = startIndex, j = endIndex; i < j; i++, j--) {
char temp = chars[i];
chars[i] = chars[j];
chars[j] = temp;
}
return new String(chars);
}
return null;
}
public static String reverse2(String str, int startIndex, int endIndex) {
if (str != null && str.length() != 0) {
String reverStr = str.substring(0, startIndex);
System.out.println(reverStr);//ab
for (int i = endIndex; i >=startIndex ; i--) {
reverStr += str.charAt(i);
}
reverStr += str.substring(endIndex + 1);
return reverStr;
}
return null;
}
public static void main(String[] args) {
String str = "abcdefg";
String reverse = reverse2(str, 2, 5);
System.out.println(reverse);
}
}
StringBuffer 和 StringBuilder
String、StringBuffer、StringBuilder 的区别
String:不可变的字符串,底层用char[]存储
StringBuffer:可变的字符串,线程安全,效率低,底层用char[]存储
StringBuilder :可变的字符串,线程不安全,效率高,底层用char[]存储
public static void main(String[] args) {
StringBuffer abc = new StringBuffer("abc");
abc.setCharAt(0, 'm');
System.out.println(abc);
StringBuffer stringBuffer = new StringBuffer();
System.out.println(stringBuffer.length());
}
常用方法
- StringBuffer append(xxx): 字符拼接
- StringBuffer delete(int start, int end):删除指定位置的内容
- StringBuffer insert(int offset, xxx):在指定位置插入 xxx
- StringBuffer reverse() :字符串反转
- int indexOf(String str):
- String substring(int start, int end):返回一个从start开始到end索引结束的左闭右开区间的子字符串
- int length()
- char charAt(int index)
- void setCharAt(int index, char ch):修改指定位置的字符
public static void main(String[] args) {
StringBuffer stringBuffer = new StringBuffer("abcdef");
stringBuffer.append(1);
stringBuffer.append('1');
System.out.println(stringBuffer);
/*stringBuffer.delete(2,4);
System.out.println(stringBuffer);*/
stringBuffer.replace(2,4,"herb");
System.out.println(stringBuffer);
stringBuffer.insert(2, "eagle");
System.out.println(stringBuffer);
stringBuffer.reverse();
System.out.println(stringBuffer);
String substring = stringBuffer.substring(1, 5);
System.out.println(substring);
}
String、StringBuffer,StringBuilder效率对比
StringBuilder > StringBuffer > String
public static void main(String[] args) {
long startTime = 0;
long endTime = 0;
StringBuffer stringBuffer = new StringBuffer("");
StringBuilder stringBuilder = new StringBuilder("");
startTime = System.currentTimeMillis();
for (int i = 0; i < 500000; i++) {
stringBuffer.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
startTime = System.currentTimeMillis();
for (int i = 0; i < 500000; i++) {
stringBuilder.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
}
public static void main(String[] args) {
long startTime = 0;
long endTime = 0;
StringBuffer stringBuffer = new StringBuffer("");
StringBuilder stringBuilder = new StringBuilder("");
startTime = System.currentTimeMillis();
for (int i = 0; i < 500000; i++) {
stringBuffer.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
startTime = System.currentTimeMillis();
for (int i = 0; i < 500000; i++) {
stringBuilder.append(String.valueOf(i));
}
endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
}