JAVA常用类学习
一、 String类
1、了解String类的特性:
- String类是被final修饰的,是无法被继承的
- 实现了Serializable接口:表示字符串是支持序列化的
- 实现了Comparable接口:表示是支持序列化的
- String类内部定义了final char[ ] value来存储数据
- 由于String内部定义了final char[ ] value来存数据,所以String类具有不可变特性
体现:- 当对字符串进行重新赋值,不能直接更改已有的值,需要重新创建一个地址空间,将这个新的字符串存进去。
- 当需要对字符串进行连接时,同样不能直接在原有的字符串上进行连接,仍然需要重新创建一个新的地址空间,然后将这个字符串存进去。
- 当需要对字符串进行更改时,需要用到replace方法,但是仍然需要重新创建地址空间
- 字符串常量池是不会存储相同的内容的字符串。
public static void main(String[] args) {
String s1 = "abc";
String s2 = "javaEE";
String s3 = "hadoop";
String s4 = "javaEEhadoop";
String s5 = "javaEE"+"hadoop";
String s6 = s2+"hadoop";
String s7 = "javaEE"+s3;
System.out.println(s4 == s5);//true
System.out.println(s4 == s6);//false
System.out.println(s4 == s7);//false
System.out.println(s6 == s7);//false
System.out.println(s6);//javaEEhadoop
System.out.println(s7);//javaEEhadoop
结论:
常量池拼接的结果仍在常量池,而常量池不会存储相同内容的字符串
例如: String s6 = s2+“hadoop”; 此时会在堆中有一个s2 然后指向字符串"javaEEhadoop"。
2、了解实例化String对象的大概过程
Person p1 = new Person("Tom");
Person p2 = new Person("Tom");
System.out.println(p1.name == p2.name);//true
p1和p2分别指向堆中各自的对象,然后指向常量池中同一个字符串的地址,所以返回true
对于 Person p = new Person(“Tom”):
创建了两个对象,一个是new Person,一个是char[ ] 对应常量池中的Tom
3、String类的转换
①、String —> 基本数据类型、基本数据类型 —>String
// 用包装类:parseXxx(str)
String str = "123";
int i = Integer.parseInt(str);
System.out.println(str);//"123"
System.out.println(i);//123
对于一个基本数据类型转化为String类:String—> xxx.valueOf(value);
int i = 2023;
String str = String.valueOf(i);
System.out.println(str);//"2023"
//或者
System.out.println(i+"");
②、String —> char[ ]/byte[ ]、char[ ]/byte[ ]—>String
char[ ] —> String
//char[] ---> String
String str = "abc";
char[] c = str.toCharArray();
System.out.println(Arrays.toString(c));//[a,b,c]
char[ ] —> String
//char[] ---> String
//调用String类的构造器
char c = new char[]{'h','e','l','l','o'};
String str = new String(c);
System.out.println(str);//hello
String —> byte[ ]:调用 getBytes[ ]方法
String str = "中国123";
byte[] bytes = str3.getBytes();//可加参数,指定编码形式进行编码
System.out.println(Arrays.toString(bytes));//使用默认字符集UTF-8进行编码
byte[ ] —> String:调用String类的构造器
String s = new String(bytes);//解码
System.out.println(s);
4、String类的常用方法
int length() : 获取字符串长度
String str = "aknasd";
int length = str.length();
System.out.println(length);
charAt(int index) :获取指定位置上的字符
String str = "acas";
str.chatAt(0);// -->'a'
indexOf() : 返回指定字符第一次出现的位置
int indexOf(int ch);//返回的是ch在字符串中第一次出现的位置
int indexOf(int ch, int fromIndex);//从fromIndex指定位置开始,获取ch在字符串中出现的位置
int indexOf(String str);//返回的是str在字符串中第一次出现的位置
int indexOf(String str, int fromIndex);//从fromIndex指定位置开始,获取str在字符串中出现的位置
int lastIndexOf(int ch);//返回的是str在字符串中最后一次出现的位置
boolean contains() :判断字符串中是否包含某一个子串
String str = "ava";
str.contains("av");//true
boolean isEmpty() : 判断字符串是否为空
String str = "";
str.isEmpty();//--->true
boolean startWith(): 判断一个字符串是否以某字符串为开头
二、StringBuffer 类和 StringBuilder 类
1、String类、StringBuffer类 和StringBuilder类的比较
String类:不可变的字符串序列。底层是使用char[ ]数组存储数据。
StringBuffer类:可变的字符串序列。底层也是使用char[ ]数组存储数据。线程安全,效率低
StringBuilder类:可变的字符串序列。底层也是使用char[ ]数组存储数据。线程不安全,效率高
对于StringBuffer添加字符串,在底层怎么实现:
//对于String:
String str = new String();//char[] value = new char[0];
str = "abc"; // value = {a,b,c};
对于StringBuffer:
StringBuffer sb = new StringBuffer(); //char[] value = new char[16] 底层创建一个长度为16的数组
sb.append('a'); // char[0] = 'a';
sb.append('b'); // char[0] = 'b';
StringBuffer在底层创建char数组时,大小为value.length()+16
StringBuffer sb1 = new StringBuffer("abc"); //char[] value = new char["abc".length()+16];
扩容时,默认扩容为原来长度的两倍+2,并将原来数组的元素复制到新的数组中。
2、StringBuffer类的常用方法
增: append(xxx) : 提供了很多append() 方法 ,用于进行字符拼接
StirngBuffer sb = new StringBuffer();
sb.append('a');
sb.append('b');
System.out.println(Arrays.toString(sb));//"ab"
删: delete(int start,int end):删除指定位置的内容
StringBuffer s = new StringBuffer("zhangtingx");
StringBuffer delete = s.delete(7,8);//[start,end)
System.out.println(delete);//zhangtigx
改:setCharAt(int n ,char ): 将指定位置的字符修改
replace(int start, int end, string str) :把[start,end)位置替换为str
StringBuffer s = new StringBuffer("zhangtingx");
s.setChatAt(0,'s');//shangtingx
s.replace(0,1,"xx");//xxhangtingx
查: char charAt(int n ):返回指定位置的char形字符
StringBuffer s = new StringBuffer("zhang");
s.charAt(0);//z
insert(int offset, xxx): 在指定位置插入xxx
StringBuffer s = new StringBuffer("zhangtingx");
s.insert(1,'3');
System.out.println(s);//z3hangtingx
3、关于String的一个算法题
给定一个字符串 s ,你需要反转字符串中每个单词的字符顺序,同时仍保留空格和单词的初始顺序。
@Test
public void test6(){
String s = "Let's take LeetCode contest";
String test = test(s);
System.out.println(test);
}
public static String test(String s){
StringBuffer buffer = new StringBuffer();
int i = 0;//用来扫描字符串
while(i<s.length()){
int start = i;//用来记录每个字母的开头位置
while(i<s.length() && s.charAt(i) != ' '){//当退出这个循环,就会获得一个字母的长度+1(因为此时i的位置为空格的位置)
i++;
}
for (int j = i-1;j>=start;j--){//j从字母的尾部位置开始
buffer.append(s.charAt(j));//start加字母的长度就是字母最后一个单词的位置,减去j,就是相当于从后往前扫描了
}
while (i<s.length() && s.charAt(i) == ' '){
i++;//让i继续往后扫描
buffer.append(' ');
}
}
return buffer.toString();
}
}
三、表示时间的类
一、jdk8.0之前表示时间的类
1、System类提供的public static long currentTimeMillis()
long l = System.currentTimeMillis();
System.out.println(l);
//用来返回当前时间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。
// > 此方法适于计算时间差,称为时间戳
2、Date类
构造器一:Date():创建一个对应当前时间的时间对象
Date d1 = new Date();
System.out.println(d1.toString());
System.out.println(d1.getTime());
构造器二: Date():指定毫秒数的Date对象
Date d2 = new Date(1681376149636L);
System.out.println(d2.toString());
3、SimpleDateTime类
3.1.两个操作:
1.1:格式化:日期--->字符串
Date date = new Date();
System.out.println(date);
SimpleDateFormat sdf = new SimpleDateFormat();
//格式化:日期--->字符串
System.out.println(sdf.format(date))
3.1.2:解析:字符串—>日期
//解析:字符串--->日期
Date date1 = sdf.parse("23-4-13 下午6:17");
System.out.println(date1);
指定格式化输出
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd G 'at' HH:mm:ss z");//年-月-日 -时-分-秒
String date2 = sdf1.format(date);
System.out.println(date2);
4、Calender类
4.1、构造器:
4.1.1、Calender为一个抽象类,调用其子类GregorianCalendar(不常用)
4.2.1、调用静态方法 Calender.getInstance();(实质还是调用了其子类)
Calendar calendar = Calendar.getInstance();
4.2、常用方法
get():
int days = calendar.get(Calendar.DAY_OF_MONTH);//获取当前日期是本月的多少天,
// 参数说明:DAY_OF_MONTH为Calendar类下声明的常量
System.out.println(days);
set()
//set()
calendar.set(Calendar.DAY_OF_MONTH,22);//修改Day_OF_MONTH的天数
days=calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);
add():
calendar.add(Calendar.DAY_OF_MONTH,2);//参数说明:amount 在日期上修改 正表示加,负数表示减
days = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days);
getTime() 日历类 —>Date类
Date time = calendar.getTime();
System.out.println(time);//结果:Mon Apr 24 20:08:40 CST 2023
setTime(): Date —> 日历类
Date date = new Date();
calendar.setTime(date);
int days1 = calendar.get(Calendar.DAY_OF_MONTH);
System.out.println(days1);//19
二、jdk8.0之后版本的时间表示
1、LocalDate、 LocalTime、LocalDateTime的使用
1.1 构造器
now()
LocalDate localDate = LocalDate.now();
LocalTime localTime = LocalTime.now();
LocalDateTime localDateTime = LocalDateTime.now();
2.2 常用方法
static of():
LocalDateTime localDateTime1 = LocalDateTime.of(2023, 4, 14, 14, 36, 55);//设置时间
System.out.println(localDateTime);
System.out.println(localDateTime1);
getXxx():获取某个时间
LocalDateTime localDateTime = LocalDateTime.now();
System.out.println(localDateTime.getDayOfMonth());
System.out.println(localDateTime.getHour());
withXxx():设置相关属性,体现了不可变性
LocalDateTime localDateTime2 = localDateTime.withDayOfMonth(10);
LocalDateTime localDateTime3 = localDateTime.withMonth(12);
System.out.println(localDateTime);
System.out.println(localDateTime2);
System.out.println(localDateTime3);
plusXxx():
LocalDateTime localDateTime4 = localDateTime.plusDays(11);
System.out.println(localDateTime4);
2、DateTimeFormatter:格式化或解析日期、时间
2.1、构造器
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");//年月日
LocalDateTime localDateTime = LocalDateTime.now();
2.2、格式化:
//格式化
String s = dateTimeFormatter.format(localDateTime);
System.out.println(s);
//解析:
TemporalAccessor parse = dateTimeFormatter.parse("2023-04-14");
System.out.println(parse);
注意:解析输出的参数时,需要跟创建对象时输入的格式化参数一致。
四、比较器
4.1、说明:为什么要使用比较器?
说明:因为类于 == != > < 等只能用于基本数据类型的比较
而对于对象的比较,两个方式:
1.实现Comparable接口
2.创建Comparator对象
4.2、自然排序:实现Comparable接口
4.2.1、实现Comparable接口的说明:
Comparable接口的使用举例:自然排序
- 像String、包装类等实现了Comparable接口,重写了compareTo(obj)方法,给出了比较两个对象的大小
- 默认进行从小到大的排序
- 重写compareTo的规则:
- 如果当前对象this大于形参对象obj,则返回正整数
- 如果当前对象this小于形参对象obj,则返回负整数
- 如果当前对象this等于形参对象obj,则返回零
- 对于自定义类来说,如果需要排序,我们可以让自定义类实现Comparable接口,并重写compareTo()方法,在compareTo方法中指明如何进行排序。
实现:
class Goods implements Comparable{
private String name;
private double price;
public Goods() {
}
public Goods(String name, double price) {
this.name = name;
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Goods{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
@Override
public int compareTo(Object o) {
if (o instanceof Goods){
Goods goods = (Goods) o;
return Double.compare(this.price,goods.price);
}
throw new RuntimeException("输入的数值有误!");
}
}
4.2.2、创建Comparator对象
实现:
public void test2(){
Goods[] goods = new Goods[4];
goods[0] = new Goods("谷歌",30);
goods[1] = new Goods("搜狗",11);
goods[2] = new Goods("百度",25);
goods[3] = new Goods("百度",40);
Arrays.sort(goods, new Comparator<Object>() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Goods && o2 instanceof Goods){
Goods g1 = (Goods) o1;
Goods g2 = (Goods) o1;
if (g1.getName().equals(g2.getName())){
return -Double.compare(g1.getPrice(),g2.getPrice());
}else {
return g1.getName().compareTo(g2.getName());
}
}
throw new RuntimeException("输入的数据类型有误!");
}
});
System.out.println(Arrays.toString(goods));
}
五、BigIneger和BigDecimal
5.1、两个类的说明:
5.1.1、BigInteger:
BigInteger :Integer类作为int的包装类,能存储的最大整型值为2的31次方-1,Long类也是有限的,最大为2^63-1。
如果要表示再大的整数,不管是基本数据类型还是他们的包装类都无能为力,更不用说进行运算了。
java.math包的BigInteger可以表示不可变的任意精度的整数。
BigInteger 提供所有 Java 的基本整数操作符的对应物,
并提供java.lang.Math 的所有相关方法另外,BiaInteger 还提供以下运算:模算术、GCD 计算、质数测试、素数生成、位操作以及一些其他操作。
5.1.2、BigInteger:
BigDecimal:一般的Float类和Double类可以用来做科学计算或工程计算,但在商业计算中,要求数了精度比较高,故用到java.math.BigDecimal类。
构造器:
public BigDecimal(double val)
BigDecimal bd1 = new BigDecimal(900303103.223);
public BigDecimal(String val)
BigDecimal bd2 = new BigDecimal("123213213123123123123");
常用方法:
BigDecimal bd2 = new BigDecimal("123415.123");
BigDecimal bd3 = new BigDecimal("11");
System.out.println(bd2.divide(bd3,BigDecimal.ROUND_HALF_UP));//ROUND_UP 四舍五入
BigDecimal bd2 = new BigDecimal("123415.123");
BigDecimal bd3 = new BigDecimal("11");
System.out.println(bd2.divide(bd3,22,BigDecimal.ROUND_HALF_UP));//22:保留22位小数,this.divide(obj)---> this/obj
public BigDecimal multiply(BigDecimal multiplicand)
public BigDecimal subtract(BigDecimal subtrahend)
六、System类:
6.1、常用方法:
- void gc():请求系统进行垃圾回收。至于系统是否会立即回收,取决于系统中垃圾回收算法的实现以及系统执行时的情况
- void exit(itn status): 该方法的作用是退出程序。其中status的值为0代表正常退出,非零代表异常退出。使用该方法可以在图形界面编程中实现程序的退出功能等。
- String getProperty(String key):获得系统中属性为key对应的值。
3中常见的参数:
java.version–> java运行时环境
java.home–>java安装目录
os.name–>操作系统的名称
os.version–>操作系统的版本
user.name–>用户的账户名称
user.home–>用户的主目录
user.dir–>用户的当前工作目录
public static void main(String[] args) {
System.out.println(java.lang.System.getProperty("java.version"));
System.out.println(java.lang.System.getProperty("java.home"));
System.out.println(java.lang.System.getProperty("os.name"));
System.out.println(java.lang.System.getProperty("os.version"));
}