1.String
1.概述
java.lang.String: 是字符串类,底层就是一个final修饰的char数组,所以String很多特性就是数组的特性
注:Java.lang是核心包,不需要导包
比如 一旦确定长度,不能更改
1.字符串一旦创建,这个字符串对象不能再更改,但变量的内容可以更换。
2.为了提升字符串的访问和存储效率,java虚拟机采用了一种缓存机制,把字符串都保存在了字符串常量池中
3.在程序执行过程中,加入要用到一个字符串a String s1 = "a";先去字符串常量池中检索是否有a,没有再创建一份
如果有了 String s2 = "a"; ,就不再创建,把已有的这个a返回
所以导致此时 使用 s1 == s2;他也是true,因为他们指向同一个字符串对象,就是a
2.基本使用
1.创建一个对象,他们都指向常量池
String s1 = "a";
String s2 = "a";
System.out.println(s1.equals(s2)); //返回值为true,比较的是值
System.out.println(s1 == s2); //返回值为true,比较的是地址
s1 = 'b'; //String一旦创建不能更改的意思是变量指向的对象中的数据不能更改,不是这个变量不能更改
//如果使用了new的方式,那么会创建堆内存对象,该字符串对象会保存在堆内存中
String s3 = new String("a");
String s4 = new String("a");
System.out.println(s3 == s4); //因为s3和s4不指向常量池,而是分别指向了堆内存,所以地址不同,为false
System.out.println(s3.equals(s4); //但是String中覆写了equals方法比较值,所以是true
注: String中对比是否相等,尽量使用equals而不去使用 ==
3.不要频繁拼接
因为字符串创建后不能更改,如果频繁拼接会频繁创建新数组频繁制造垃圾,效率很低,并且垃圾回收可能也会出问题
4.构造方法(String是特殊的,可以像基本数据类型一样赋值)
1.字面量: String s1 = "asad";
2.
3.字节数组:byte[] bytes = {97,46,7,84,46};
String s3 = new String(bytes);
System.out.println(s3); //将字节转化为字符串输出 abcdef
4.字节数组,只截取一部分,4表示起始下标(包含),2表述个数
String s4 = new String(byte,4,2);
System.out.println(s4); //ef
5.字符数组
char[] chars = {'a','b','c','d'};
String s5 = new String(chars);
System.out.println(s5);
6.字符数组,只截取一部分,1表示起始下标(包含),2表示个数
String s6 = new String(chars,1,2);
System.out.println(s6);
5.常用方法
学习API:1.功能是什么
2.入参和出参是什么
3.怎么用
(一定要记住API有哪些功能,入参出参怎么用都可以百度,但一定要记住哪些功能可以用API解决)
1. char charAt(int index): 返回该字符串中,指定位置(下标)的字符
String s1 = "qwerasdf";
char c1 = s1.charAt(2);
System.out.println(c1); //e
2.boolean endsWith(String suffix):判断字符串是否以指定字符串结尾
boolean startsWith(String prefix):同上,判断开始
System.out.println("Hello.java".endsWith(".java")); //注意:有空格就无法匹配上
3.boolean equalslgnoreCase(String str):不区分大小写比较两个字符是否相等
System.out.println("abc".equalslgnoreCase("aBc"));
4.byte[] getBytes(): 把字符串转化为字节数组并返回
byte[] bytes = "abc".getBytes();
for(int i=0;i<bytes.length;i++){
System.out.println(bytes[i]);
}
5.char[] toCharArray():把字符串转换为字符数组并返回
char[] chars = "abc".toCharArray();
for(int i=0;i<chars,length;i++){
System.out.println(chars[i]);
}
6. int indexOf(String str):获取该字符串中指定字符串的起始索引,找不到返回-1
System.out.println("askdhwqer".indexOf("kd")); //2
7.int indexOf(String str,int index); 从指定位置开始查找(包含)获取该字符串中指定字符串的起始索引,找不到返回-1
System.out.println("askdhwqer".indexOf("s",5)); //-1
8.index lastIndexOf(String str):同上,最后一次出现的索引,找不到返回-1
System.out.println("sagsadgsdfsdag".lastIndexOf("a")); //2
9.int length(): 返回该字符串的长度
System.out.println("abc".length());
10.String replaceAII(String regex.String replacement); 替换指定字符,支持正则表达式
String replace(String str.String replacement);不支持正则表达式
// 用1 把 a 替换了并返回新的字符串
// 支持正则表达式,但是没有写正则表达式 是没有区别的
System.out.println("hucgasdqweasd".replaceAll("a", "1"));
System.out.println("hucgasdqweasd".replace("a", "1"));
// 因为 . 在正则表达式中,代表任意字符
System.out.println("qwe.rty.yui.uio".replaceAll(".", ","));
// 可以使用 \ 转义
System.out.println("qwe.rty.yui.uio".replaceAll("\\.", ","));
System.out.println("qwe.rty.yui.uio".replace(".", ","));
11.String[] split(String regex):分割字符串,返回字符串数组,支持正则表达式
注意: 点 需要转义
String s2 = "2020.1.14";
String[] arr = s2.split("\\.");
for(int i=0;i<arr.length;i++){
System.out.println(arr[i]);
}
12.String substring(int begin); 获取该字符串中,以某个下标起始的子字符串(包含)
System.out.println("abcdef".substring(2)); //cdef
13.String substring(int begin,int end); 获取该字符串中,以某个下标起始(包含)到
某个下标结束的子字符串(不包含)
System.out.println("avcdef".substring(2,4)); //cd
14.String trim(): 去除字符串两边的空格
System.out.println(" advc dsff ".trim());
15. //String toUpperCase(): 转大写
//String toLowerCase(): 转小写
System.out.println("asd".toUpperCase());
16.//static String valueOf(Object obj): 调用该对象的toString方法,如果为null,则不再
调用toString,而是返回字符串null
String s = null;
//打印一个引用类型的时候,会自动调用String的valueOf,所以会自动调用toString方法
System.out.println(s);
6.注意
String a = "a";
String b = "b";
String str = "ab";
//字面量相加,在编译阶段就把 + 去掉了
String d = "a" + "b";
//true
System.out.ptintln(d == str);
//true
System.out.println(d.equals(str));
//变量相加,因为变量的值是可变的,运算之前没有办法确定变量的值,
所以没办法优化只能转化为new的方式,重新创建并拼接字符串
String c = a+b;
String e = a+"b";
//false
System.out.println(c == str);
//true
System.out.println(c.equals(str));
//上面相加因为变量的值无法去欸但那个,如果声明为常量,可以优化
2.StringBuffer 和 StringBuilder
1.概述
都是字符串缓冲区,可以做拼接操作
区别:
String:底层是char数组,定长,一旦创建不可更改,不适合做字符串拼接操作
StringBuffer和StringBuilder:底层是char数组,变长,预先在内存中申请一块空间,
用来保存很多字符,如果空间不够会自动扩容
默认容量为16,扩大容量(当前容量+1)*2, 16->34->70
这俩区别:
StringBuffer线程安全,在多线程环境下,不会出现问题
StringBuilder非线程安全,在多线程环境下可能会出现问题
2.基本使用
创建一个对象
StringBuilder sb = new StringBuilder();
String[] arr = {"a","b","c"};
for(int i = 0;i<arr.length;i++){
//append就是添加操作,做拼接操作,可以链式调用
sb.append(arr[i]).append(",");
}
//toString可以把StringBuilder转换为String类型
String str = sb.toStrign();
System.out.println(str);
3.常用方法
//反转
sb.reberse();
//获取已有元素个数
System.out.println(sb.length());
//当前容量(数组长度)
System.out.println(sb.capacity());
//toString可以把StringBuilder转换为String类型
String str = sb.toString();
3.包装类
1.概述
问:想要对基本类型进行更多操作怎么办?
答:最方便的方式就是将其封装成对象,因为在对象描述中就可以定义更多的属性和行为
对该基本数据类型进行操作我们不需要对基本类型进行封装,JDK已经为我们封装好了
概念:
1.装箱就是自动将基本数据类型转换为包装器类型
2.拆箱就是自动将包装器类型转换为基本数据类型
*char的封装类型为Character,int的封装类型为Integer,其他都是首字母大写
2.使用
//基本类型
byte b1 = 12;
//封装为包装类
Byte b2 = new Byte(b1);
m1(b2);
3.Integer
1.基本使用
//最大值
System.out.println(Integer.MAX_VALUE);
//创建对象
Integer i1 = new Integer(123);
//传递字符串也可以,但必须是纯数字
Integer i2 = new Integer("123");
2.相互转换(重要)
//int->Integer
Integer i1 = new Integer(123);
i1 = Integer.valueOf(123);
//Integer->int
int i2 = i1.intValue();
//String->Integer
Integer i3 = new Integer("123");
i3 = Integer.valueOf("123");
//Integer->String
String string = i3.toString();
//int->String
String string1 = 123+"";
//String->int
//重要 static int parseInt(String str):把纯数字的字符串转换为int类型
int i4 = Integer.parseInt("123");
3.常用方法
//把数字以二进制的字符串形式,并返回
String s1 = Integer.toBinaryString(10);
//同上,八进制
s1 = Integer.toOctalString(10);
//同上,十六进制
s1 = Integer.toHexString(10);
System.out.println(s1);
4.自动装箱与自动拆箱
八种包装类都覆写了 toString 和 equals()方法
Integer i3 = 123; //编译之后相当于 Integer i3 = Integer.valueOf(123);
int i4 = i3; //编译之后就等于 int i4 = i3.intValue();
m1(i3);
//1234为int型, 会先进行自动装箱为Integer类型,然后再发生多态转型为Object类型
m1(1234);
5.深入整型常量池
Integer i1 = new Integer(10);
Integer i2 = new Integer(10);
System.out.println(i1 == i2); //false
System.out.println(i1.equals(i2)); //true
Integer i3 = Integer.valueOf(123);
Integer i4 = Integer.valueOf(123);
System.out.println(i3 == i4); //true
Integer i5 = 12; //编译后 Integer.valueOf(12);
Integer i6 = 12;
System.out.println(i5 == i6); //true
Integer i7 = 222;
Integer i8 = 222;
System.out.println(i7 == i8); //false,因为整形常量池的方位在-128~127之间
判断这个数值是否在-128~127之间,不在就new对象 p14页
6.总结
常量池就是提前准备好一些对象,当我们要保存数据的时候,发现已经创建好了,就直接拿走,不需要重新创建
总结:
当我们通过new Integer(xx)创建对象的时候,不管值是多少,==永远是false
当我们使用Integer i1 = xxx;这种方式的时候,编译之后会转换为Integer.valueOf();这种方式会经过整形常量池
假如xxx这个值在-128到127之间,则不需要new对象,而是使用常量池中以创建的对象
否则不在范围内,则还是等于 new Integer(xxx)这种方式
因此 Integer i1 = xxx; i2 = xxx; 如果xxx在-128~127之间,则i1==i2 是true
如果通过构造方法直接创建对象是不经过常量池的
4.System
1.概述
System类提供的public static long currentTimeMillis()用来返回当前时 间与1970年1月1日0时0分0秒之间以毫秒为单位的时间差。
此方法适于计算时间差。
1.System类代表系统,系统级的很多属性和控制方法都放置在该类的内部。 该类位于java.lang包。
2.由于该类的构造器是private的,所以无法创建该类的对象,也就是无法实 例化该类。其内部的成员变量和成员方法都是static的,所以也可以很方便 的进行调用。
3.成员变量
4.System类内部包含in、out和err三个成员变量,分别代表标准输入流
(键盘输入),标准输出流(显示器)和标准错误输出流(显示器)。
5.成员方法
6.native long currentTimeMillis():
该方法的作用是返回当前的计算机时间,时间的表达格式为当前计算机时
间和GMT时间(格林威治时间)1970年1月1号0时0分0秒所差的毫秒数。
7.void exit(int status):
该方法的作用是退出程序。其中status的值为0代表正常退出,非零代表
异常退出。使用该方法可以在图形界面编程中实现程序的退出功能等。
2.常用方法
//标准输出->打印到控制台
System.out.println(123);
//表示错误,以红色字体展示到控制台
System.err.println(123);
//in表示标准输入,接收控制台输入的信息
new Scanner(System.in);
//获取时间原点到当前时间的毫秒数(1970.1.1 8:0:0)
long startTime = System.currentTimeMillis();
System.out.println("正在执行");
long endTime = System.currentTimeMillis();
System.out.println("耗时:" + (endTime-startTime));
//退出JVM虚拟机,0表示正常关闭,1表示异常关闭,一般用于图形界面关闭窗口
System.exit(0);
//执行不到
System.out.println("================");
5.Date
1.概述
获取时间和时间操作
2.构造方法
//获取当前系统时间
Date d1 = new Date();
//传入毫秒数,获取时间原点到指定毫秒数的时间
Date d2 = new Date(1000);
//Fri Jan 14 16:15:57 CST 2022
System.out.println(d1);
3.常用方法
//获取指定时间的毫秒数
System.out.println(d1.getTime());
//把时间转换为 字符串类型
System.out.println(d1.toString());
4.格式化
年 y
月 M
日 d
时 H
分 m
秒 s
毫秒 S
//创建时间格式化对象
SimpleDateFormat sdf new SimpleDateFormat("yyyy年MM月dd日 HH:mm:ss SSS");
//格式化返回字符串
String string = sdf.format(d1);
System.out.println(string);
//时间格式的字符串转换为Date对象
String strDate = "2022/01/14 16:21:36";
//格式化对象的时间格式,要和字符串的格式一致
sdf = new SimpleDateFormat(yyyy/MM/dd HH:mm:ss);
//转换返回Date对象
Date date = sdf.parse(strDate);
System.out.println(date);
5.Calendar
// 获取当前日历
Calendar c = Calendar.getInstance();
// 获取当前是本周第几天 , 周日是第一天
System.out.println(c.get(Calendar.DAY_OF_WEEK));
// 年
System.out.println(c.get(Calendar.YEAR));
// 月 , 0 是1月 , 11是12月, 所以 结果 +1 才是正确的
System.out.println(c.get(Calendar.MONTH)+1);
// 日 获取今天是当前月中第几天
System.out.println(c.get(Calendar.DAY_OF_MONTH));
// 时 12小时制
System.out.println(c.get(Calendar.HOUR));
// 24小时制
System.out.println(c.get(Calendar.HOUR_OF_DAY));
// 分
System.out.println(c.get(Calendar.MINUTE));
// 秒
System.out.println(c.get(Calendar.SECOND));
6.Random
1.概述
随机数从0开始
2.使用
// 创建随机数生成器
Random r = new Random();
// 在int范围内 随机生成一个数字
int i = r.nextInt();
System.out.println(i);
// 传入10 说明要在 0~9之间生成
i = r.nextInt(10);
System.out.println(i);
// 生成 10~22
// nextInt(最大值 - 最小值 + 1) + 最小值
int result = r.nextInt(100 - 20 + 1) + 20;
System.out.println(result);
多线程:并发:同时出发,并行:同时进行