一. 包装类
1. 为什么要定义包装类
- 为每一种基本数据类型定义包装类,可以在包装类中定义操作该基本类型的属性和方法
- 在定义属性时,可以把数据类型定义为包装类,使用起来和基本类型一样(可以自动装箱,拆箱),关键默认值可以为null,更加符合实际场景。
基本类型 | 包装类 | 属性 | 方法 |
---|---|---|---|
byte | Byte | MAX_VALUE MIN_VALUE | parseByte(字符串) |
short | Short | MAX_VALUE MIN_VALUE | parseShort(字符串) |
int | Integer | MAX_VALUE MIN_VALUE | parseInt(字符串) |
long | Long | MAX_VALUE MIN_VALUE | parseLong(字符串) |
float | Float | MAX_VALUE MIN_VALUE | parseFloat(字符串) |
double | Double | MAX_VALUE MIN_VALUE | parseDouble(字符串) |
boolean | Boolean | parseBoolean(字符串) | |
char | Character | MAX_VALUE MIN_VALUE | |
包装类是类,类就是引用类型,引用类型的值可以为null
null有什么好处呢?null就是一个表示没有值的意思
1. 自动装箱
可以直接把一个基本类型数据赋值给该类型包装类的对象
2. 自动拆箱
把一个包装类的对象,可以直接赋值给一个基本类型的变量
package com.qf;
public class Demo03 {
public static void main(String[] args) {
/*
* Integer 只有有参构造方法,要定义一个整数参数
*/
Integer i = new Integer(5);
/*
* 可以直接把一个int类型数据赋值给Integer对象
* 自动装箱
*/
Integer ii = Integer.valueOf(6); // new Integer(6);
/*
* intValue() 获取当前Integer的整数值
*/
int i2 = ii.intValue();
/*
* 把一个Integer类型的对象,可以直接赋值给一个int类型的变量
* 自动拆箱
*/
int i3 = ii; // ii.intValue();
/*
* byte Byte
* short Short
* int Integer
* long Long
* float Float
* double Double
*/
Double d = 3.14; //new Double(3.14) 自动装箱
double d2 = d; //d.doubleValue() 自动拆箱
//把其他类型的自动装箱和拆箱写出来
Byte b = 4; // new Byte(4);
byte b2 = b; //b.byteValue();
Boolean b3 = true;
boolean b4 = b3;
}
}
package com.qf;
public class Demo02 {
public static void main(String[] args) {
Student stu = new Student();
stu.age = 17; //自动装箱
int age = stu.age; //自动拆箱
System.out.println(stu);
}
}
class Student {
/*
* from now on
* 在一个类中,如果属性的数据类型为基本类型,那么就需要定义为该基本类型的包装类
* 因为包装类可以为null,更加符合我们具体的场景
*
* 包装类的变量和基本类型的变量用起来一样,因为有自动装箱和自动拆箱
*/
String name;
Integer age; // age=null
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
//定义属性使用包装类,用起来和基本类型一致,还可以为null
class Emp {
private String name;
private Integer age;
private Double salary;
private Boolean isManeger;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Double getSalary() {
return salary;
}
public void setSalary(Double salary) {
this.salary = salary;
}
public Boolean getIsManeger() {
return isManeger;
}
public void setIsManeger(Boolean isManeger) {
this.isManeger = isManeger;
}
}
二. 字符串
什么是字符串:
由多个字符组成的内容或者信息,我们成为字符串,使用String数据类型来表示。
1. 字符串的定义
String 变量名 = "字符串值";
//以及下面所有的构造方法
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
//String 构造方法
public String() {
this.value = "".value;
}
public String(String original) {
this.value = original.value;
this.hash = original.hash;
}
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length);
}
public String(char value[], int offset, int count) {
//方法体
}
public String(int[] codePoints, int offset, int count) {
//方法体
}
public String(byte bytes[], int offset, int length, String charsetName){}
public String(byte bytes[], int offset, int length) {}
//重写了toString
public String toString() {
return this;
}
}
2. 字符串对象的创建
3. 重写equals方法
String 重写了equals方法,比较两个字符串的逻辑: 如果两个字符串中的值相等,那么就返回true
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
//强制类型转化
String anotherString = (String)anObject;
//value为String类属性,表示的是字符串的值
//通过length属性,获取字符串中有多少个字符
int n = value.length;
//比较两个字符串的长度是否一样,如果不一样直接返回false
if (n == anotherString.value.length) {
//把两个字符串的值,转化为字符数组
char v1[] = value;
char v2[] = anotherString.value;
//逐个的比较两个字符串中的字符,只要有一个不相等,就直接返回false
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
//如果两个字符串中的值相等,那么就返回true
return true;
}
}
//如果数据类型不一致,返回false
return false;
}
package com.qf;
public class Demo05_2 {
public static void main(String[] args) {
String str1 = "jackma";
String str2 = "jackma";
//str1,str2都指向到常量池中的相同的常量对象
boolean r1 = str1 == str2; //true
boolean r2 = str1.equals(str2); //true
System.out.println(r1);
System.out.println(r2);
System.out.println("--------------------------------------------");
String str3 = new String("jackma");
String str4 = new String("jackma");
//str3,str4分别指向堆中不同的对象
boolean r3 = str3 == str4; // false
//String字符串重写了equals方法,逻辑就是比较两个字符串的值
boolean r4 = str3.equals(str4); // true
System.out.println(r3);
System.out.println(r4);
System.out.println("--------------------------------------------");
boolean r5 = str1 == str4; //false
boolean r6 = str2 == str4; //false
boolean r7 = str1.equals(str4); //true
boolean r8 = str2.equals(str4); //true
}
}
4. String 定义的字符串不可改变
String 定义变量是不能被修改的,修改只是变量的指向。
image-20220413151943467[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0Nnbx6RO-1650637915890)(D:\千峰\作业\05文件\day17\03_随堂笔记\image-20220413151943467.png)] |
package com.qf;
public class Demo05_3 {
public static void main(String[] args) {
/*
* String 定义的字符串不能被修改
*/
String str = "jackma";
System.out.println(str);
str += " hello";
System.out.println(str);
}
}
5. 字符串的常用方法
//根据下标获取字符
public char charAt(int index);
//判断当前字符串中是否包含str
public boolean contains(String str);
//将字符串转换成数组。
public char[] toCharArray();
//查找str⾸次出现的下标,存在,则返回该下标;不存在,则返回-1
public int indexOf(String str);
//返回字符串的长度
public int length();
//去掉字符串前后的空格
public String trim();
//将⼩写转成⼤写
public String toUpperCase();
//判断字符串是否以str结尾
public boolean endsWith(String str)
//将旧字符串替换成新字符串
public String replace(char oldChar,char newChar);
//根据str做拆分
public String[] split(String str);
//在字符串中截取出⼀个⼦字符串
public String subString(int beginIndex,int endIndex);
package com.qf;
import java.util.Arrays;
public class Demo05_4 {
public static void main(String[] args) {
//String 常用的方法
/*
* char charAt(int index); 获取指定下标的字符
* 1. 字符串中每个字符都有一个下标
* 2. 下标从0开始,每次自增1
*/
String str = "jackma";
char c = str.charAt(4);
System.out.println(c);
/*
* boolean contains(String str); 判断当前字符串中是否包含str
*/
str = "jackma";
boolean b1 = str.contains("j");
boolean b2 = str.contains("jak");
System.out.println(b2);
/*
* char[] toCharArray(); 将字符串转换成数组。
* 数组中元素的顺序和字符串的顺序一致
*/
str = "jackma";
char[] charArray = str.toCharArray();
System.out.println(Arrays.toString(charArray));
/*
* indexOf获取字符串
* 1. 如果参数为一个字符,获取其 首次 出现的下标
* 2. 如果参数为多个字符,获取其第一个字符 首次出现的下标
* 2.1 前提一定包含此字符串
* 3. 如果不包含该字符串,直接返回-1
*/
str = "jackma";
int index1 = str.indexOf("j");
int index2 = str.indexOf("a");
int index3 = str.indexOf("ck"); // 包含的ck中c的下标
int index4 = str.indexOf("ckn"); // -1
System.out.println(index4);
/*
* lastIndexOf() 获取最后一次出现的下标 如果不包含返回-1
*/
str = "jackma";
int index5 = str.lastIndexOf("a");
System.out.println(index5);
//三国.演义.ppt 获取点的下标
/*
* int length(); 返回字符串包含字符的长度(个数)
* 空格也是一个字符
*/
str = "jackma ";
int len = str.length();
System.out.println(len);
//结合charAt() 遍历字符串
for(int i=0; i<str.length(); i++) {
System.out.println(str.charAt(i));
}
/*
* String trim(); 去掉字符串 前后 的空格
* 只能去除前后的空格,不会去除中间的空格
*/
str = " jack ma ";
str = str.trim();
System.out.println(str);
/*
* String toUpperCase(); 将小写转成大写
*/
str = "jackma";
str = str.toUpperCase();
System.out.println(str);
/*
* toLowerCase(); 将大写转成小写
*/
str = "JACKMA";
str = str.toLowerCase();
System.out.println(str);
/*
* boolean endsWith(); 判断字符串是否以str结尾
*/
str = "jackma";
boolean b3 = str.endsWith("kma");
System.out.println(b3);
/*
* boolean startsWith(String str) 判断字符串是否以str开头
*/
str = "jackma";
boolean b4 = str.startsWith("jd");
System.out.println(b4);
/*
* 根据str做拆分,把拆分的每一份都放到数组中
*/
str = "aa,bb,cc";
String[] arr = str.split(","); // {"aa","bb","cc"}
String[] arr2 = str.split("bb"); // {"aa,",",cc"}
System.out.println(Arrays.toString(arr2));
/*
*
* String subString(int beginIndex); 截取字符串
* 从此beginIndex下标开始截取,包含此下标,一直到最后
*
* String subString(int beginIndex,int endIndex); 截取字符串
* 从此beginIndex下标开始截取,一直截取到endIndex下标的位置
* 包含beginIndex下标字符,不包含endIndex下标字符 (包含前不包含后)
*
*
*/
str = "abcdefg";
String str2 = str.substring(2); //bcdefg cdefg
System.out.println(str2);
String str3 = str.substring(0, 2);
System.out.println(str3); //ab
/*
* 基本类型转为字符串
*/
int i = 6;
String str4 = ""+i;
double d = 3.14;
String str5 = ""+d;
float f = 4.4f;
String str6 = String.valueOf(i);
}
}
更多方法参考手册
三. 可变字符串
意思就是当进行字符串拼接时,不再常量池创建新的常量对象
- StringBuffer
- 线程安全
- StringBuilder
- 线程不安全
两个对象的用法,一模一样
package com.qf;
public class Demo06 {
public static void main(String[] args) {
/*
* 我们使用可变字符串的目的,就是在操作字符串时,不再创建新的字符串常量
* 底层操作的就是会自动扩容的字符数组
*/
StringBuffer sf = new StringBuffer();
StringBuilder sd = new StringBuilder();
//append(字符串) 追加 拼接字符串
sf.append("hello");
sf.append(" world");
sf.append("!");
System.out.println(sf);
sd.append("吃了");
sd.append("吗");
sd.append("!");
System.out.println(sd);
}
}
package com.qf;
public class Demo06_2 {
public static void main(String[] args) {
StringBuffer sf = new StringBuffer();
//append:拼接字符串
sf.append("hello");
sf.append("world");
// insert 在执行位置插入
sf.insert(2, "www");
System.out.println(sf);
//delete hewwwlloworld
sf.delete(0, 2); //包含前 不包含后
System.out.println(sf);
//replace替换 wwwlloworld
sf.replace(0, 2, "pppp"); //包含前 不包含后
System.out.println(sf);
//length() 获取字符串长度
int length = sf.length();
System.out.println(length);
}
}