String类
final类, 不可变的字符序列, 字符串常量, 它的值在创建之后不能更改, String对象的字符内容是存储在一个**字符数组value[]**中的
- String声明为final, 不可被继承
- 实现了Serializable接口: 表示字符串是支持序列化的
- 实现了Comparable接口: 表示String可以比较大小
- String内部定义了final char[] value用于存储字符串数据
- String: 代表不可变的字符序列. 简称: 不可变性
- 不可变性: 当对字符串重新赋值时, 需要重新指定内存区域赋值, 不能使用原有的value赋值
- 不可变性: 当对现有的字符串进行操作时, 也需要重新指定内存区域赋值, 不能使用原有的value赋值
- 当调用String的replace方法修改指定字符或字符串时, 也需要重新指定内存区域赋值, 不能使用原有的value赋值
- 通过字面量的方式给一个字符串赋值, 此时的字符串值声明在字符串常量池中
- 字符串常量池中是不会存储相同内容的字符串
- 等号赋值
String s1 = "abc"; //字面量的定义方式
String s2 = "abc";
s1 = "hello";
System.out.println(s1); //hello
System.out.println(s2); //abc
- 加法
String s3 = "abc";
s3 += "def";
System.out.println(s3); //abcdef
- replace(“a”,“b”)替换 把a替换成b
String s4 = "abc";
String s5 = s4.replace("a", "m");
System.out.println(s4); //abc
System.out.println(s5); //mbc
String的实例化方式
- 通过字面量定义的方式
- 通过new+构造器的方式
- 字面量定义的方式, 此时s1和s2的数据JavaEE声明在方法区的字符串常量池中, 栈–>常量池
String s1 = "javaEE";
String s2 = "javaEE";
- new+构造器的方式, 在堆空间中开辟空间, 栈–>堆–>常量池
String s3 = new String(javaEE);
String s4 = new String(javaEE);
System.out.println(s1 == s2); //true
System.out.println(s3 == s4); //false
System.out.println(s1 == s3); //false
[小问题] String s = new String(“abc”); 方式创建对象, 在内存中创建了几个对象?
两个, 一个是堆空间中new结构, 另一个是char[]对应的常量池中的数据: “abc”
字符串拼接
String s1 = "javaEE";
String s2 = "hadoop";
String s3 = "javaEEhadoop";
String s4 = "javaEE" + "hadoop"
String s5 = s1 + "hadoop";
String s6 = "javaEE" + s2;
String s7 = s1 + s2;
- 常量与常量的拼接结果在常量池, 且常量池中不会存在相同内容的常量
System.out.println(s3 == s4); //true
- 只要有一个是变量, 结果就在堆中
System.out.println(s3 == s5); //false
System.out.println(s3 == s6); //false
System.out.println(s5 == s6); //false
System.out.println(s3 == s7); //false
System.out.println(s5 == s7); //false
System.out.println(s6 == s7); //false
- intern() 方法返回字符串对象的规范化表示形式
String s8 = s5.intern();
System.out.println(s3 == s8); //true 返回值得到的s8使用的常量值中已经存在的"JavaEEhadoop"
String方法
- length() 长度
String s1 = "helloworld";
System.out.println(s1.length()); // 10 字符串长度
- charAt(index) 返回指定下标字符
System.out.println(s1.charAt(0)); // h 返回指定下标字符
- isEmpty 判断是否为空串
System.out.println(s1.isEmpty); //false 是否为空串
-
toLowerCase 改成小写
-
toUpperCase 改成大写
-
trim 去除首尾空格,中间空格不变
String s3 = " hel lo w or ld ";
System.out.println(s3.trim); //hel lo w or ld 去除首尾空格,中间空格不变
- equalsIgnoreCase 忽略大小写比较
String s4 = "HelloWORLD"
System.out.println(s1.equalsIgnoreCase); //true 忽略大小写比较
- concat(str) 拼接字符串
System.out.println(s1.concat("hhh")); //helloworldhhh 拼接字符串
- compareTo 逐个相减比较
String s5 = "abc";
String s6 = new String("abe");
System.out.println(s5.compareTo(s6)); //-2 (a-a)+(b-b)+(c-e)=-2 一个一个相减比较
- substring(index, index) 截取
String s7 = "好像不认识我了";
System.out.println(s7.substring(2)); //不认识我了
System.out.println(s7.substring(2,5)); //不认识 截取[2,5)
-
endWith() 是否以指定的后缀结束
-
startsWith() 是否以指定的前缀开始
-
startsWith(str,2) 从指定位置以此字符串开头
-
contains(str) 是否包含某串
-
indexof(str) 返回第一次出现的位置, 出现返回索引位置, 不存在返回-1
indexof("lo");//返回第一次出现的位置, 出现返回索引位置, 不存在返回-1
-
lastIndexof(str) 从后往前找,最后出现的索引
-
replace(char old, char new) 替换
-
replace(替换index, char new) 指定位置替换
特殊
- \ \d数字, 如果有数字, 则用逗号代替数组, ^开头$结尾符号用空串代替, 也就是去除首位符号
String str = "12hello34world5java4556mysql34";
String string = str.replaceAll("\\d",",").replace("^,|,$","");
System.out.println(string);//hello,world,java,mysql
- 判断str字符串中是否全部由数字组成
String str = "12345";
boolean matches = str.matches("\\d+");
System.out.println(matches);
- 判断这是否是一个杭州的固定电话
String tel = "0571-4534289";
boolean result = tel.matches("0571-\\d{7,8}");
System.out.println(result);
String的转换
- String–>基本数据类型, 包装类, 调用包装类的静态方法: parseXxx(str)
String str1 = "123";
int num = (int)str1;//错误的, 强转用于子父类
int num = Integer.parseInt(str1);
- 基本数据类型, 包装类–>String, 调用String重载的valueOf(xxx)
String str2 = String.valueOf(num);
String str3 = num + "";//有变量num参与, 所以str3相当于new, 是在堆里, 不等于str1
-
String–>char[] 调用toCharArray()
-
char[]–>String 调用String构造器
char[] arr = new char[]{'h','e','l','l','o'}
String str = new String(arr); //转换完成
- String–>byte[]: 调用String的getBytes();
String str1 = "abc123";
byte[] bytes = str1.getBytes();
System.out.println(Arrays.toString(bytes)); //输出ascll码
- byte[]–>String
String s2 = new String(bytes);
时间戳
JDK8之前
- System.currentTimeMillis() 返回当前事件到1970.01.01.00.00.00的毫秒数,成为时间戳
long time = System.currentTimeMillis();
System.out.println(time);
- 构造器一 new Date()
Date date1 = new Date();
System.out.println(date1.toString()); //月 星期 日 时分秒 时区 年
System.out.println(date1.getTime)); //毫秒数
- 构造器二 new Date(毫秒数)
Date date2 = new Date(2343211432);
System.out.println(date2.toString()); //月 星期 日 时分秒 时区 年
- **如何把utils转换为sql?**默认utils
Date date4 = new java.sql.Date(毫秒数); //多态的了, 用父类造子类
java.sql.Date date5 = (java.sql.Date) date4;
- SimpleDateFormat
//实例化:默认的构造器
SimpleDateFormat sdf = new SimpleDateFormat();
//格式化: 日期-->字符串
Date date = new Date();
System.out.println(date);//Mon Feb 18 11:40:48 GMT+08:00 2019
String format = sdf.format(date);
System.out.println(format);//19-2-28 上午11:40
//解析: 字符串-->日期
String str = "19-2-28 上午11:40";
Date date1 = sdf.parse(str);
System.out.println(date1);
//***********************************************
//指定的格式
new SimpleDateFormate sdf1 = new SimpleDateFormate("yyyy-MM-dd hh-mm-ss");//好多格式自己去查
- Calendar日历类
//实例化
//方式一, 创建其子类(GregorianCalendar)的对象
//方式二:调用其静态方法getInstance()
Calendar calendar = Calendar.getInstance();
//2.常用方法
//get()
int days = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);//18号
//set()
cltendar.set(Calendar.DAY_OF_MONTH,22);
days = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);//22
//add()
calendar.add(Calendar.DAY_OF_MONTH,3);//如果减天数那就加个-减号
days = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);//25
//getTime 日历类-->Date
Date date = calendar.getTime();//输出的日也是我们修改过的
//setTime Date-->日历类
Date date1 = new Date();
calendar.setTime(date1);
System.out.println(days);//18
一月是0,星期日是1
JDK8之后
//now现在
LocalDate localDate = LocalDate.now();
LocalDate localTime = LocalTime.now();
LocalDate localDateTime = LocalDateTime.now();
//of设置指定的年月日
//年月日时分秒没有偏移量
LocalDate localDateTime1 = LocalDateTime.now(2020,10,6,11,11,11);
//get
getDayOfMonth
getDayOfWeek
getMonth
太多了,知道有这一回事就行了
Comparable
比较
String, 包装类等实现了Comparable接口, 重写了compareTo()方法, 给出了比较两个对象大小的方法
String[] arr = new String[}{"AA","CC","KK","MM","GG","DD"};
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
重写compareTo(obj)的规则:
- 如果当前对象this大于形参对象obj, 则返回正整数
- 如果当前对象this小于形参对象obj, 则返回负整数
- 如果当前对象this等于形参对象obj, 则返回零
对于自定义类来说, 如果需要排序, 我们可以让自定义类实现Comparable接口, 重写CompareTo(obj), 在CompareTo(obj)中指明如何排序
Class Goods implements Comparable{
private String name;
private double price;
构造方法, get, set, toString
@Override//价格从低到高
public int compareTo(Object o){
//方式一
if(o instanceof Goods){//判断是否属于
Goods goods = (Goods)o;//强转
if(this.price>goods.price){
return 1;
}else if(this.price<goods.price){
return -1;
}else{
return 0;
//return this.name.compareTo(goods.name);
}
//方式二
//return Double.compare(this.price, goods.price);
}else{
//如果不是商品
throw new RuntimeException("传入的数据类型不一致!");
}
}
}
class Test{
Goods[] arr = new Goods[4];
arr[0] = new Goods("苹果",34);
arr[1] = new Goods("栗子",43);
arr[2] = new Goods("香蕉",12);
arr[3] = new Goods("土豆",65);
Arrays.sort(arr);
System.out.println(Arrays.toString(arr));
}