学习内容
-
包装类型(基本数据类型的包装类型)
-
String字符串常用方法
-
StringBuffer与Stringbuilder
-
日期和时间处理工具类
-
System,Math,Random,UUID等工具类
-
枚举类型
-
File类
-
递归算法
目录
1.包装类型
Java面向对象编程语言–>并不是完全面向对象(基本数据类型),所有Java提供了基本数据类型包装类–>对象。
-
基本数据类型时默认值是什么???–>int–>0
-
引用数据类型默认值是什么?–>null–>用它可以表示不存在的东西
包装数据类型是基本数据类型–>8个基本数据类型的包装类–>这8个中,只有少部分是我们常用的。
基本数据类型 | 包装数据类型 |
---|---|
byte | Byte |
short | Short |
int | Integer–>常用的 |
long | Long |
float | Float |
double | Double–>常用的 |
char | Character |
boolean | Boolean |
包装类型中所有的方法基本都是相同的,学会一个包装类其他的都是照搬代码就可以实现。
1.1.Integer的基本用法
-
Integer(int value)
:构造方法,通过int类型构造一个Integer数字类型 -
Integer(String s)
:构造方法,通过String类型(数字)构造一个Integer数字类型
1.2.包装类型的使用
public class IntegerDemo {
public static void main(String[] args) {
// 使用integer包装类创建int类型数据
Integer i1 = new Integer(123);
// 使用String字符串类型创建时一定不要有非数字之外的内容,否则报异常:class NumberFormatException extends IllegalArgumentException {
Integer i2 = new Integer("123");
System.out.println(i1);
System.out.println(i2);
// 第二种方式赋值
Integer i3 = 12;
// 这种方式不同于构造方法,不允许出现这种赋值方式
// Integer i4 = "123";
System.out.println(i3);
int ii = 15;
// 由于直接赋值时就是int类型,所以我们使用int定一个变量也是可以赋值的
Integer i4 = ii;
System.out.println(i4);
/**
* 使用包装类的方法
*/
// 使用Integer静态方法parseInt(String s)将字符串转为int类型
int i = Integer.parseInt("1245");
System.out.println(i);
// 使用Integer静态方法valueOf(String s)将字符串转为Integer类型
Integer integer = Integer.valueOf("1245");
System.out.println(integer);
// 其他包装类中的也是这种使用方式
double v = Double.parseDouble("12.34");
Double aDouble = Double.valueOf("12.34");
System.out.println(v);
System.out.println(aDouble);
// 包装类可以直接计算
System.out.println(v * aDouble);
// 将包装类型转为String类型-->toString
String s = integer.toString();
String s1 = aDouble.toString();
System.out.println(s);
System.out.println(s1);
}
}
1.3.自动装箱与自动拆箱(重点)
-
自动装箱与自动拆箱是JDK1.5之后加入的新的特性,在给包装类赋值时可以直接赋值当前数据类型,而不用使用
new 包装类型
这种方式赋值或创建对象(也是Java中的特殊类) -
基本数据类中的自动装箱
-
Integer i = 10
–>自动装箱,但是JDK1.5之前这种用法是错误的,只能通过new来创建Integer i = new Integer(10)
-
JVM虚拟机替我们做了一个
Integer.valueOf(10)
操作 -
自动装箱就是将基本数据类直接给包装类赋值
-
-
基本数据类型的自动拆箱
-
将包装类型转换为基本数据类型时直接赋值即可
-
-
// 使用自动装箱赋值 Integer integer1 = 10; // 使用自动拆箱 int int1 = integer1; // 自动装箱与自动拆箱目的其实就是为了基本数据类型与包装数据类型之间的转换,但实际上可能不需要
1.4.自动装箱的缓存问题
public class IntegerDemo {
public static void main(String[] args) {
// 使用自动装箱赋值
Integer integer1 = 10;
// 使用自动拆箱
int int1 = integer1;
// 自动装箱缓存问题
Integer integer2 = 127;
Integer integer3 = 127;
// 比较判断
System.out.println(integer2 == integer3);// true
// 自动装箱缓存问题
Integer integer4 = 1270;
Integer integer5 = 1270;
// 比较判断
System.out.println(integer4 == integer5);// false
// 所有的整数类型的包装类是有缓存的(为了速度),-128至127-->超出这个范围之后则使用的就不是缓存了,而是正经点对象
// 变成对象后==判断就是地址了所以结果为false
/**
* public static Integer valueOf(int i) {
* // 验证传入的i值是否是大于等于缓存中最小值并且判断是否是小于缓存中的最大值
* if (i >= IntegerCache.low && i <= IntegerCache.high)
* // 如果成立则存入缓存-->-128至127
* return IntegerCache.cache[i + (-IntegerCache.low)];
* // 创建对象存入数据
* return new Integer(i);
* }
*/
// 将2进制,8进制,16进制的数据转为10进制-->了解即可
String hexString = Integer.toHexString(1564352415);
System.out.println(hexString);
}
}
1.5.包装类与基本数据类型的默认值
-
基本数据类型根据基本数据决定
-
包装类型则全都是null
1.6.使用场景
-
在程序中0或者0.0这都是数据,会导致程序的不严谨,而包装类型都是null所代表的是无数据能够解决数据不严谨的问题。
1.7.Java大数字类型(整数的了解,浮点类型掌握)
Java中数据类型int和long都是范围有限的保不齐啥时候就超出了范围,然后Java就出现了更大数据类型,就是大数字类型。
BigInteger–>大整数
BigDecimal–>大浮点(掌握)
1. `BigDecimal add(BigDecimal decimal)`加法
2. `BigDecimal subtract(BigDecimal decimal)`减法
3. `BigDecimal multiply(BigDecimal decimal)`乘法
4. `BigDecimal divide(BigDecimal decimal)`除法
5. `注意:做运算时一定是使用字符串赋值`
1. 例如:`BigDecimal bigDecimal = new BigDecimal(“0.1”);`
public class BigNumber {
public static void main(String[] args) {
// 打印输出0.3+0.3+0.3+0.1
System.out.println(0.3 + 0.3 + 0.3 + 0.1);
// 正常对像,是不存在加减乘除的操作的,通过方法解决,一定是使用字符串赋值
BigDecimal bigDecimal1 = new BigDecimal("0.1");
BigDecimal bigDecimal2 = new BigDecimal("0.3");
BigDecimal bigDecimal3 = new BigDecimal("0.3");
BigDecimal bigDecimal4 = new BigDecimal("0.3");
BigDecimal add = bigDecimal1.add(bigDecimal2).add(bigDecimal3).add(bigDecimal4);
System.out.println(add);
}
}
2.String字符串常用方法
字符串常用方法Java提供给我们的针对于字符串所做的很多的操作工具,比如字符串分割,字符串的替换等等。
-
String类是由Unicode字符序列组成并且是不可变,只要字符串创建出之后就无法修改(内容无法修改)
-
String类的源码–>String就是final修饰的字符数组,所以其值不可改变。
-
public final class String implements java.io.Serializable, Comparable<String>, CharSequence { // 字符串表示时就是一个字符数组并且是final修饰的不可逆最终的 private final char value[]; private int hash; // Default to 0 private static final long serialVersionUID = -6849794470754667710L; private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0]; public String() { // 调用当前对象的value this.value = "".value; } public String(String original) { // 调用当前对象的value,赋值 this.value = original.value; this.hash = original.hash; } }
-
字符串使用案例
public class StringDemo { public static void main(String[] args) { // 定义字符串 String str = "123"; // 字符串更改 str = "abc"; // 正常创建String对象时是new方式 // 定义两个字符串然后使用==进行比较 String str1 = "abc"; String str2 = "abc"; System.out.println(str1 == str2);// true // 使用new对象可能创建的是2个对象,也有可能是1个对象 String str3 = new String("abc"); String str4 = new String("abc"); System.out.println(str3 == str4);// false // 拼接案例 str1 = "abcd"; // JVM编译后就默认是一个abcd的字符串,字面意思,虚拟机知道你的数据是啥,并且知道你的数据是给谁 str2 = "ab" + "cd"; System.out.println(str1 == str2);// false true // 拼接案例 str1 = "abcd"; // JVM编译后就默认是一个abcd的字符串 // 字面意思,虚拟机知道你的数据是啥,并且知道你的数据是给谁 str2 = "ab"; str3 = str2 + "cd"; // JVM虚拟机是不会查看变量中的数据的,只要你的编译没有问题则代表当前代码没问题 str4 = str2 + "cd"; System.out.println(str1 == str3);// false System.out.println(str4 == str3);// false } }
-
String内存的存储方式
2.1.String的常用的构造方法
构造方法 | 解释 |
---|---|
String(); | 创建String对象 |
String(String str); | 创建字符串对象 |
String(byte[] bytes); | 使用byte数组创建字符串(byte-ascii码表) |
String(char[] chars); | 将char数组转为字符串 |
// 使用String构造方法定义字符串
// byte数组
byte[] bytes = {97, 98, 99, 100};
// 使用bytes创建String
String str1 = new String(bytes);
System.out.println(str1);
// 使用char数组
// char数组
char[] chars = {'我', '是', '彭', '于', '晏'};
// 使用chars创建字符串
String str2 = new String(chars);
System.out.println(str2);
2.2.常用的字符串方法
方法名 | 说明 |
---|---|
char charAt(int index) | 返回该字符串指定位置的字符 |
int compareTo(String anotherString) | 对比两个字符串大小,以ascii码表对比,如果是中文是Unicode码表对比 |
String concat(String str) | 将此字符串与传入字符串拼接 |
boolean contains(CharSequence s) | 当此字符串包含指定的字符串的字符串值,相同返回true,否则false |
boolean equals(Object anObject) | 比较两个字符串的内容是否相同,相同返回true,否则false |
byte[] getBytes() | 返回一个byte数组,后期会用 |
byte[] getBytes(Charset charset) | 返回String编码为一个字节序列使用给定的 charset字符编码,结果存放到一个新的字节数组。 |
int indexOf(String str)方法重载 | 查找指定字符串中是否存在字符,存在则返回此字符的下标索引,否则返回-1 |
boolean isEmpty() | 返回指定字符串是否为空 |
int lastIndexOf(String str)方法重载 | 返回字符串的指定子字符中最后出现的位置 |
int length() | 返回字符串的长度 |
String replace(String oldStr, String newStr) | 使用新字符串替换旧字符串,字符串替换 |
String[] split(String regex) | 字符串通过指定字符切割返回字符串数组 |
boolean startsWith(String prefix) | 返回字符串是否以xxx开头 |
String substring(int beginIndex, int endIndex) | 截取字符串,开始位置以及结束位置返回中间的内容 |
Char[] toCharArray() | 将字符串返回字符数组 |
String toLowerCase() | 将字符串返回小写 |
String toUpperCase() | 将字符串返回大写 |
String trim() | 去除字符串前后的空格 |
static String valueOf(基本数据类型) | 将指定基本数据类转为字符串 |
2.3.equals解释
字符串中的equals最终是比较内容是否相同
// String的equals方法-->object参数(让传的是String类)String是否可转object
public boolean equals(Object anObject) {
// ==:地址-->this当前对象与传入的anObject地址相同
if (this == anObject) {
// 直接反回true
return true;
}
// instanceof:验证是否是相同类型-->类型不同
if (anObject instanceof String) {
// anObject强转为String类型
String anotherString = (String) anObject;
// value-->this当前对象的char数组的长度
int n = value.length;
// 用this当前对象的长度对比anotherString长度是否是相等
if (n == anotherString.value.length) {
// this的char数组又赋值给v1
char v1[] = value;
// 将传入的字符串的char数组又转为新的char数组v2
char v2[] = anotherString.value;
// 定义了一个变量赋值0-->将数组内容取出,从0开始
int i = 0;
// 循环判断
while (n-- != 0) {
// 验证char数组中的每一个相同位置的元素是否不相等
if (v1[i] != v2[i])
// 如果不相等直接返回false
return false;
// 更新下标索引变量
i++;
}
// 返回true代表内容相同
return true;
}
}
// 返回false代表内容不相同
return false;
}
public class StringDemo {
public static void main(String[] args) throws UnsupportedEncodingException {
// // 定义字符串
// String str = "123";
// // 字符串更改
// str = "abc";
//
// // 正常创建String对象时是new方式
// // 定义两个字符串然后使用==进行比较
// String str1 = "abc";
// String str2 = "abc";
// System.out.println(str1 == str2);// true
//
//
// // 使用new对象可能创建的是2个对象,也有可能是1个对象
// String str3 = new String("abc");
// String str4 = new String("abc");
// System.out.println(str3 == str4);// false
//
//
// // 拼接案例
// str1 = "abcd";
// // JVM编译后就默认是一个abcd的字符串,字面意思,虚拟机知道你的数据是啥,并且知道你的数据是给谁
// str2 = "ab" + "cd";
// System.out.println(str1 == str2);// false true
//
//
// // 拼接案例
// str1 = "abcd";
// // JVM编译后就默认是一个abcd的字符串
// // 字面意思,虚拟机知道你的数据是啥,并且知道你的数据是给谁
// str2 = "ab";
// str3 = str2 + "cd";
// // JVM虚拟机是不会查看变量中的数据的,只要你的编译没有问题则代表当前代码没问题
// str4 = str2 + "cd";
// System.out.println(str1 == str3);// false
// System.out.println(str4 == str3);// false
// 使用String构造方法定义字符串
// byte数组
// byte[] bytes = {97, 98, 99, 100};
// // 使用bytes创建String
// String str1 = new String(bytes);
// System.out.println(str1);
//
// // 使用char数组
// // char数组
// char[] chars = {'我', '是', '彭', '于', '晏'};
// // 使用chars创建字符串
// String str2 = new String(chars);
// System.out.println(str2);
// String a = "d";
// String b = "b";
// System.out.println(a.compareTo(b));
// String常用方法
String str1 = "字符串常用方法";
String str2 = "字符串常用方法.";
String str3 = str1 + str2;
// charAt返回指定位置的字符
// System.out.println(str1.charAt(-2));
// compareTo-->1-127是为ascii码的值,用的Unicode
System.out.println(str1.compareTo(str2));
int i = str1.charAt(3);
System.out.println(i);
// 输出0-65535所有的字符
for (int j = 0; j < 65535; j++) {
System.out.println((char) j + ":" + j);
}
// concat拼接字符串
System.out.println(str1.concat(str2));
// contains查找指定字符串是否存在
System.out.println(str1.contains("方法"));
// getBytes()返回字节数组
System.out.println(str1.getBytes());
System.out.println(str1.getBytes("UTF-8"));
// indexOf返回字符第一次出现的位置
System.out.println(str3.indexOf("常"));
// lastIndexOf返回字符第一次出现的位置
System.out.println(str3.lastIndexOf("常"));
// isEmpty()验证字符串是否为空
System.out.println(str1.isEmpty());
// length返回字符串长度,从1开始
System.out.println(str1.length());
// replace字符串替换
System.out.println(str1.replace("常用", "不常用"));
String str4 = "你这个大傻瓜!";
System.out.println(str4.replace("傻瓜", "**"));
// split返回指定任意内容的分割字符串数组
str4 = "i like you but i don't love you";
String[] strs = str4.split(" ");
/*for (int j = 0; j < strs.length; j++) {
System.out.print(strs[j]);
}*/
System.out.println(Arrays.toString(strs));
// startsWith字符串是否以指定字符串开头
System.out.println(str4.startsWith("i likeyou"));
// endWith字符串是否以指定字符串结尾
str4 = "www.bjpowernode.com";
System.out.println(str4.endsWith(".com"));
// substring字符串截取,截取指定下标开始到结尾位置的字符串
System.out.println(str4.substring(4, 15));
// toCharArray返回字符数组
System.out.println(Arrays.toString(str4.toCharArray()));
// toUpperCase将字符串(英文)转为大写
str4 = "i like you but i don't love you啊啊啊啊";
String str5 = str4.toUpperCase();
System.out.println(str5);
// toLowerCase将字符串(英文)转为小写
System.out.println(str5.toLowerCase());
// trim取出左右空格
str1 = " 彭 于 晏 ";
System.out.println(str1);
System.out.println(str1.trim());
// valueOf()返回基本数据类型的字符串
System.out.println(String.valueOf(12.34));
// equals()对比字符串值是否相同
// ==对比的是基本数据类型值,引用数据类型对比地址
str1 = "abcd";
str2 = "ab";
str3 = str2 + "cd";
System.out.println(str1 == str3);
// 如果是引用数据类型就必须是使用方法进行对比,因为==对比引用数据类型时是对比的地址
System.out.println(str1.equals(str3));
str1 = null;
// 这种调用可能会造成空指针异常
// System.out.println(str1.equals(str3));
// 这种绝对出现不了空指针异常
System.out.println("abcd".equals(str1));
System.out.println(str1 == null);
// 如果想要使用字符串的方法如何确保不会出现空指针异常
// 使用if判断
// if (str1 != null && str1.isEmpty()) {
//
// }
/**
*
* ==和equals区别是什么?
* * ==一般是用于比较基本数据类型的值是否相等,在对比引用数据类型比较的是地址
* * equals在String未重写时比较的还是地址是否相等,String重写之后比较的是字符串内容
*/
}
3.StringBuffer与Stringbuilder
String–>存放字符串的,但是是不可更改的字符串,这样会影响我们程序的性能,所以出现StringBuffer和StringBuilder两个类,他们都是用于存放字符串,但是不同点是内容可变,但是在使用StringBuffer和StringBuilder的时是不能直接赋值。
使用场景:如果存在频繁的创建或修改删除字符串时就需要使用StringBuffer或StringBuilder,来创建字符串,原因不会造成资源的浪费。
StringBuffer
-
一个线程安全的、可变的字符序列。字符串缓冲区类似于String ,但可以修改。在任何时候它都包含一些特定的字符序列,但是序列的长度和内容可以通过某些方法调用来改变。
-
线程安全但是效率低。
StringBuilder
-
一个线程不安全的,可变的字符序列。此类提供与StringBuffer兼容的 API,但不保证同步。此类设计用于在单个线程正在使用字符串缓冲区的地方(通常情况下)用作StringBuffer的替代品。在可能的情况下,建议优先使用此类而不是StringBuffer ,因为它在大多数实现下会更快。
-
线程不安全但是效率高。
3.1.StringBuffer
1、构造方法
-
StringBuffer中的常用方法
-
StringBuffer append(String str)
:在原本的内容中追加内容-
注意事项:返回值为this,所代表的是当前对象(最终是相同的指向,指到相同的地址)
-
-
StringBuffer insert(int offset, String str)
-
offset:指定字符串位置插入新的内容
-
str:插入的字符串
-
-
StringBuffer delete(int start, int end)
:删除指定起始位置到结束位置的内容-
start:起始下标索引
-
end:结束下标索引
-
-
StringBuffer replace(int start, int end, String str)
:修改字符串-
start:起始位置
-
end:结束位置
-
str:修改的字符串内容
-
-
StringBuffer reverse()
:将此字符串反转 -
char charAt(int index)
:查找指定下标索引位置的字符 -
int indexOf(String str)
:在字符串中查找指定字符串是否存在,第一次出现的位置 -
int lastIndexOf(String str)
:在字符串中查找指定字符串是否存在,最后一次出现的位置 -
String substring(int start, int end)
:字符串的截取 -
void setLength(int newLength)
:设置新的长度
-
-
StringBuffer案例
-
public class StringBufferDemo01 { public static void main(String[] args) { // 创建StringBuffer的对象 StringBuffer sb = new StringBuffer("我是彭于晏"); // this:当前对象-->地址 StringBuffer append = sb.append("我真他**的帅啊!"); System.out.println(sb); sb.append(",吃饭能免费不???"); System.out.println(sb); System.out.println(append); append.append("能免费我就吃!"); System.out.println(sb); System.out.println(append); // insert():插入数据 sb.insert(6, "是"); System.out.println(sb); System.out.println(append); // delete(14, sb.length()):删除指定开始结束之间的内容 sb.delete(14, sb.length() - 1); System.out.println(sb); System.out.println(append); // replace修改字符串内容 sb.replace(2, 5, "吴彦祖"); System.out.println(sb); System.out.println(append); // reverse反转字符串 sb.reverse(); System.out.println(sb); System.out.println(append); // 测试三个字符串的添加速度(String,StringBuffer,StringBuilder)-->添加10000次 // String // 取出时间当前时间戳-->毫秒 long start = System.currentTimeMillis(); // 定义字符串 String str1 = ""; // 执行1W次循环添加 for (int i = 0; i < 100000; i++) { str1 += i; } // 取出结束时间-->毫秒 long end = System.currentTimeMillis(); // 相减,查看用到的时间 System.out.println("String添加1W次耗时:" + (end - start)); start = System.currentTimeMillis(); StringBuffer sb1 = new StringBuffer(); for (int i = 0; i < 100000; i++) { sb1.append(i); } end = System.currentTimeMillis(); System.out.println("StringBuffer添加1W次耗时:" + (end - start)); start = System.currentTimeMillis(); StringBuilder sb2 = new StringBuilder(); for (int i = 0; i < 100000; i++) { sb2.append(i); } end = System.currentTimeMillis(); System.out.println("StringBuilder添加1W次耗时:" + (end - start)); } }
-
- StringBuilder案例
string使用他的方法验证输入内容只允许存在中文不允许,符号字符数字等等内容
如果存在非中文内容则抛自定义异常(运行期异常)
自定义异常:
public class MyException extends RuntimeException {
public MyException() {
}
public MyException(String message) {
super(message);
}
}
代码:
public static void main(String[] args) {
// 输入姓名验证是否是中文,如果存在符号或单词数字,则代表不是姓名
// 遍历0-65535所有的Unicode码 13312-40917(中文)
// for (int i = 0; i < 65535; i++) {
// System.out.println((char) i + ":" + i);
// }
// 定义姓名
String name = "彭于晏@";
// 验证姓名中是否存在字母,数字,符号等内容
for (int i = 0; i < name.length(); i++) {
if (name.charAt(i) < 13312 || name.charAt(i) > 40917) {
System.out.println("你这姓名有点问题,思考一下是因为啥");
// 只要找到了非中文内容则直接结束循环
// break;
// 使用抛出异常的方式就不需要break
throw new MyException("你这姓名有点问题,思考一下是因为啥");
}
}
}
4.日期和时间处理工具类
日期和时间处理工具,处理时间的,让原本中国人看着不得劲儿的日期格式转为我们看着得劲儿的样式。
程序中的时间就是一条线,一头到另一头,程序中的时间起始位置是1970年1月1日00:00:00–>时间戳(从1970年1月1日00:00:00到此时此刻的毫秒或秒值)
如何获取从1970年1月1日00:00:00到此时此刻的毫秒?
long l = System.currentTimeMillis();
此时此刻,就是1970年1月1日00:00:00时间到现在的时间所用的时间。
4.1.日期类型Date
-
Date是Java提供给我们针对于日期输出,将毫秒改为年月日的日期(可以包含年月日小时分钟秒等),JDK1.0时存在的
-
Date提供了2个简单的构造方法
-
public Date()
:无参构造方法用于定义此时此刻的时间-
此构造方法中调用了
this(System.currentTimeMillis());
相当于调用了下面的带参构造方法,设置此时此刻的时间
-
-
public Date(long date)
:给定一个时间戳生成时间 -
// 无参就是获取当前日期时间 Date date = new Date(); System.out.println(date); // 带参构造方法-->参数是long类型,所以Java中数字默认是int类型需要加l转为long date = new Date(19649898140447l); System.out.println(date);
-
Date常用方法
-
public boolean before(Date when)
:用于验证日期是否早于某个日期 -
public boolean after(Date when)
:用于验证此日期是否在指定日期之后。 -
public boolean equals(Object obj)
:比较两个日期是否相等。 -
public void setTime(long time)
:将此Date对象设置为表示 1970 年 1 月 1 日 00:00:00 GMT 之后的time毫秒的时间点。 -
public long getTime()
:返回自 1970 年 1 月 1 日 00:00:00 GMT 以来此Date对象表示的毫秒数。 -
public class DateTimeDemo { public static void main(String[] args) { // Java提供给我们最简单一种获取时间戳的方式 long l = System.currentTimeMillis(); System.out.println(l); // 无参就是获取当前日期时间 Date date1 = new Date(); System.out.println(date1); // 带参构造方法 Date date2 = new Date(19649898140447l); System.out.println(date2); // 比较日期是否早于指定日期 boolean before = date1.before(date2); System.out.println(before); // 比较日期是否晚于指定日期 boolean after = date1.after(date2); System.out.println(after); // 获取当前Date的时间戳 long time1 = date1.getTime(); long time2 = date2.getTime(); if (time1 > time2) { System.out.println("time1:" + time1 + ",time2:" + time2 + ",time1晚于于time2"); } else { System.out.println("time1:" + time1 + ",time2:" + time2 + ",time1早于time2"); } // 重新设置date日期 System.out.println("使用setTime前" + date1); date1.setTime(1649898779053000l); System.out.println("使用setTime后" + date1); } }
4.2.日期类型格式化类
日期格式化类提供了2中方式
-
DateFormat:(不常用的,了解)
-
用于整理日期的格式
-
DateFormat是抽象类因此无法实例化对象,只能通过方法获取实例
-
获取实例方法
-
public final static DateFormat getDateTimeInstance(int dateStyle, int timeStyle)
:通过此静态方法获取日期时间实例-
dateStyle:日期格式
-
timeStyle:时间格式
-
DateFormat.LONG
参数,代表长中文格式 -
public class DateTimeDemo { public static void main(String[] args) { // Java提供给我们最简单一种获取时间戳的方式 long l = System.currentTimeMillis(); System.out.println(l); // 无参就是获取当前日期时间 Date date1 = new Date(); System.out.println(date1); // 带参构造方法 Date date2 = new Date(19649898140447l); System.out.println(date2); // DateFormat日期格式化,DateFormat是一个抽象类,无法实例化对象,通过getDataInstance获取实例 DateFormat dateFormat = DateFormat.getDateInstance(); // 格式化日期format方法用于格式化日期,默认的格式是(年-月-日) String format = dateFormat.format(date1); System.out.println("未格式化:" + date1); System.out.println("已格式化:" + format); // DateFormat日期格式化,的getTimeInstance获取实例 // DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG); // DateFormat.LONG-->格式化的方式是什么-->长中文时间 // 原方法public final static DateFormat getDateTimeInstance(int dateStyle, int timeStyle) DateFormat dateFormat1 = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG); // 设置日期时间进行格式化 String format1 = dateFormat1.format(date2); System.out.println(format1); } }
-
-
-
-
SimpleDateFormat:(常用的)–>
extends DateFormat
的儿子-
用于整理日期的格式
-
日期格式化表
-
-
构造方法
-
public SimpleDateFormat()// 纯创建对象,使用默认的日期格式
: -
public SimpleDateFormat(String pattern)// 给定一个日期格式创建对象
:
-
-
格式化方法
-
public final String format(Date date)
;给定日期返回格式化后的日期字符串
-
-
- 案例
-
public class DateTimeDemo {
public static void main(String[] args) {
// Java提供给我们最简单一种获取时间戳的方式
long l = System.currentTimeMillis();
System.out.println(l);
// 无参就是获取当前日期时间
Date date1 = new Date();
System.out.println(date1);
// 带参构造方法
Date date2 = new Date(19649898140447l);
System.out.println(date2);
// 简单日期格式化SimpleDateFormat
/**
* public SimpleDateFormat()// 纯创建对象,使用默认的日期格式
* public SimpleDateFormat(String pattern)// 给定一个日期格式创建对象
*/
// 日期修改为此时此刻
date1.setTime(System.currentTimeMillis());
// 默认日期格式创建
SimpleDateFormat sdf = new SimpleDateFormat();
// 格式化日期
String format2 = sdf.format(date1);
System.out.println(format2);
// 自定义日期创建-->注意在格式化日期时有固定的格式Y代表的是年,M代表的是月d代表是日不能乱起
SimpleDateFormat sdf1 = new SimpleDateFormat("YYYY年MM月dd日----HH点mm分ss秒SSSS毫秒");
// 格式化日期
format2 = sdf1.format(date1);
System.out.println(format2);
}
}
4.3.Calendar(日历类)
在原本的日期的基础上可以增加或减少日期时间等信息,针对日期时间操作–>年月日时分秒
Calendar是一个抽象类,同样无法实例化对象,如果获取则使用getInstance获取实例。
获取实例对象
-
Calendar.getInstance()
:获取的是GregorianCalendar获取到的实例对象
获取年月日等日期时间
-
public int get(int field)
:给定获取类型,返回当前类型的年月日等信息
设置年月日等日期时间
-
public void set(int field, int value)
:设置日期–>设置时可以超出日期,但实际上没有50月,向上增加–>12月后增加1年,在从1-12月-
field:设置的是年月日的什么日期
-
value:设置的是多少
-
返回设置后的日期
-
public final Date getTime()
:返回设置后的日期
代码:
public class CalendarDemo {
public static void main(String[] args) {
// 获取Calendar日历类实例-->getInstance获取-->GregorianCalendar获取到的实例对象
Calendar calendar = Calendar.getInstance();
// 打印Calendar信息
System.out.println(calendar);
// 获取年月日-->参数是int类型,使用的指定常量值获取年月日
int year = calendar.get(Calendar.YEAR);
System.out.println(year);
// 获取一年中的第几天
int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);
System.out.println(dayOfYear);
// 获取月份-->从0开始获取,所以结果要加1
int month = calendar.get(Calendar.MONTH) + 1;
System.out.println(month);
// 设置年月日时间-->设置月份50,但实际上没有50月,向上增加-->12月后增加1年,在从1-12月
// calendar.set(Calendar.MONTH, 5000);
// 设置完毕后获取年月
year = calendar.get(Calendar.YEAR);
// 获取月份-->从0开始获取,所以结果要加1
month = calendar.get(Calendar.MONTH);
// 设置天数-->设置天数仅仅只是当月的天数,如果超出范围则从1重新循环
calendar.set(Calendar.DAY_OF_MONTH, 32);
// 获取天数
int dayOfMonth = calendar.get(Calendar.DAY_OF_MONTH);
// 设置小时-->设置小时仅仅只是当天的小时,如果超出范围则从0重新循环
calendar.set(Calendar.HOUR_OF_DAY, 50);
// 第二种小时设置
calendar.set(Calendar.HOUR, 50);
// 获取当天小时
int hour = calendar.get(Calendar.HOUR_OF_DAY);
System.out.println(year + "-" + month + "-" + dayOfMonth + "-" + hour);
// 获取小时
int hour1 = calendar.get(Calendar.HOUR);
System.out.println(hour1);
// 返回设置后的日期
Date date = calendar.getTime();
Calendar instance = Calendar.getInstance();
Date date1 = instance.getTime();
// 格式化日期输出样式
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
String formatDate = sdf.format(date1);
System.out.println(formatDate);
}
}
5.System,Math,Random,UUID工具类
5.1. System类–>系统类
通过System能够在控制台打印输入语句,也可使用标准输入流,还可以获取计算机相关信息,Java虚拟机相关信息。
输入输出属性:
out–>
public final static PrintStream out
:标准输出err–>
public final static PrintStream err
:标准输出–>错误信息in–>
public final static InputStream in
:标准输入方法:
public static native long currentTimeMillis()
:获取1970-1-1到现在的时间戳(毫秒级)
public static native long nanoTime()
:以纳秒输出正在运行的Java虚拟机的资源值
public static java.util.Map<String,String> getenv()
:获取系统相关信息(非常全)
public static void exit(int status)
:退出Java虚拟机环境,结束虚拟机
public static Properties getProperties()
:获取JVM虚拟机系统所有参数信息
public static String getProperty(String key)
:获取JVM虚拟机系统单独信息
key:是获取的信息是什么,可以通过
getProperties()
获取出来所有的key
5.2Math数学类
针对数学相关的操作,数学类中方法基本都是静态的所以不需要创建对象,直接对象名调用即可
静态属性
Math.PI
:π值静态方法:
public static int abs(int a)
:返回绝对值–>有方法重载
public static int max(int a, int b)
:返回最大值–>有方法重载
public static int max(int a, int b)
:返回最小值–>有方法重载
public static double random()
:返回0-1的随机数
public static double ceil(double a)
:返回天花板值
public static double floor(double a)
:返回底板值
public static double pow(double a, double b)
:返回次幂数
public class MathDemo {
public static void main(String[] args) {
// 数学类中方法基本都是静态的所以不需要创建对象,直接对象名调用即可
// 计算圆周率->PI-3.14-->radius-->PI*2*radius
// PI-->Math数学类提供的就有
double radius = 5;
double circumference = 2 * Math.PI * radius;
System.out.println("周长:" + circumference);
// 返回绝对值
int abs = Math.abs(-10);
System.out.println(abs);
// 返回最大值
int max = Math.max(10, 11);
System.out.println(max);
// 返回最小值
int min = Math.min(10, 11);
System.out.println(min);
// 返回0-1的随机数
for (int i = 0; i < 100; i++) {
double random = Math.random();
// System.out.println(random * 1000);
System.out.println(random);
}
// ceil天花板值-->1.1=2
System.out.println(Math.ceil(1.1));
System.out.println(Math.ceil(1.9));
// 底板值-->1.9=1
System.out.println(Math.floor(1.9));
// 次幂
double pow = Math.pow(2, 10);
System.out.println(pow);
}
}
5.3.Random–>随机数
获取随机数
Random–>不安全的
SecureRandom–>安全的
方法
public int nextInt(int bound)
:获取随机数
bound:随机数范围
public class RandomDemo {
public static void main(String[] args) {
// 获取随机数-->非安全的
Random random = new Random();
// 设置随机数值
for (int i = 0; i < 1000; i++) {
int i1 = random.nextInt(100);
if (i1 == 0) {
System.out.println("有0");
}
if (i1 == 100) {
System.out.println("有100");
}
}
// 使用安全的随机数
SecureRandom secureRandom = new SecureRandom();
// 设置随机数值
for (int i = 0; i < 1000; i++) {
int i1 = secureRandom.nextInt(100);
if (i1 == 0) {
System.out.println("有0");
}
if (i1 == 100) {
System.out.println("有100");
}
}
}
}
5.4.UUID–>获取随机ID
获取不重复的ID值,使用的是静态方法,所以不需要创建UUID的对象
方法:
UUID.randomUUID()
:返回一个36位的随机的数
public class UuidDemo {
public static void main(String[] args) {
// 使用的UUID的静态方法获取随机ID值
UUID uuid = UUID.randomUUID();
// 通过toString转为String类型
String uuidRandom = uuid.toString();
System.out.println(uuid);
System.out.println(uuidRandom);
// 使用随机数生成不重复的id
SecureRandom secureRandom = new SecureRandom();
// 26字母+0-9的数字
String idRandom = "qwertyuiopasdfghjklzxcvbnm0123456789";
// 定义StringBuilder拼接字符
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 100; i++) {
// 取出string中的单个字符
char c = idRandom.charAt(secureRandom.nextInt(36));
stringBuilder.append(c);
}
// 自己生成的随机数
System.out.println(stringBuilder);
}
}
6.枚举类型
枚举类型–>数据JDK1.5新增的特性,他是一种新的类型(数据类型),允许使用常量来表示特定的数据片段,并且是类型安全的形式表示。
在使用实体类时会有性别–>2种(男/女)
定义格式:
enum 枚举名称{
枚举体(常量列表);// 常量列表既是value也是key
}
// 定义枚举类
public enum Sex {
// 枚举体(常量列表)
boy, girl;
}
// 使用javap反编译后的源码
/*public final class com.zzcsy.enumdemo.Sex extends java.lang.Enum<com.bjpowernode.enumdemo.Sex>{
public static final com.zzcsy.enumdemo.Sex boy;// 等同于变量名称,类型是自己本身
public static final com.zzcsy.enumdemo.Sex girl;// 等同于变量名称,类型是自己本身
public static com.zzcsy.enumdemo.Sex[]values();// 获取所有常量值
public static com.zzcsy.enumdemo.Sex valueOf(java.lang.String);// 指定常量值获取常量值
static {};
}*/
使用:
public class EnumDemo {
public static void main(String[] args) {
// 实例化people对象
People people = new People();
people.setName("小明");
people.setSex(Sex.boy);
System.out.println(people);
System.out.println(Sex.boy);
// values方法获取所有的常量
Sex[] values = Sex.values();
System.out.println(Arrays.toString(values));
// valueOf(String)
Sex sex = Sex.valueOf("boy");
System.out.println(sex);
}
}
7.File类
file–>文件,可以操作系统中的文件或文件夹增删改查,所代表的就是修改内容移动文件等等的操作windows10–>权限,C盘有可能不让创建或者删除操作(权限不够)文件或文件夹的操作有一概念–>IO流的操作
-
I:input:输入,从磁盘到Java程序
-
O:output:输出,Java程序到磁盘
File构造方法:
-
public File(String pathname)
:通过指定路径创建File对象,路径必须给他,不能null,哪怕是一个””空字符串都没有问题。public File(String pathname) { // 验证传入的是否是null if (pathname == null) { // 如果是null则直接抛出空指针异常 throw new NullPointerException(); } this.path = fs.normalize(pathname); this.prefixLength = fs.prefixLength(this.path); }
-
public File(String parent, String child)
:给定一个父级目录,一个自己目录,创建File对象-
parent:父级目录
-
child:子级目录/文件
-
File中的常用方法:
-
public String getAbsolutePath()
:获取文件的绝对路径 -
public String getName()
:获取文件或目录的名称 -
public String getParent()
:获取当前文件或目录的父级目录(绝对路径的父级目录) -
public long lastModified()
:获取文件或目录最后修改的时间 -
public long length()
:获取文件或目录的大小(字节表示) -
代码
public class FileDemo { public static void main(String[] args) { // File-->java.io包下的 String pathName = "D:/file/ideaIUPortable-破解版.zip"; // 创建File对象 File file = new File(pathName); // 创建File对象 File file1 = new File("D:/java"); // 创建File对象 // file = new File("D:/java", "src.zip"); // getAbsolutePath-->返回当前文件或目录的绝对路径-->从磁盘的盘符开始的位置到,当前文件的位置 String path = file.getAbsolutePath(); System.out.println(path); // getPath-->返回当前路径 System.out.println(file.getPath()); // getName-->获取最后一级文件或目录名称 System.out.println(file.getName()); // getParent-->从当前文件或目录找到他的父级路径(绝对父级路径) System.out.println(file.getParent()); // lastModified-->获取文件或目录的最后修改时间 long l = file.lastModified(); // 创建SimpleDateFormat日期格式化 SimpleDateFormat sdf = new SimpleDateFormat("YYYY-MM-dd HH:mm:ss"); // format格式化日期格式-->给了一个new Date String format = sdf.format(new Date(l)); // 输出最终结果 System.out.println(l); System.out.println(format);// 2022-04-14 14:29:51 // length-->获取当前文件的大小(字节为单位) long length = file.length(); System.out.println(length); } }
File判断方法:
-
public boolean exists()
:测试此抽象路径名表示的文件或目录是否存在。 -
public boolean isDirectory()
:测试此抽象路径名表示的文件是否为目录。如果给的是个假目录他则返回false -
public boolean isFile()
:测试此抽象路径名表示的文件是否为普通文件。如果是返回true否则false,如果文件不存在则返回false -
public boolean isHidden()
:测试此抽象路径名命名的文件是否为隐藏文件。 -
public boolean canRead()
:测试应用程序是否可以读取的文件。 -
public boolean canWrite()
:测试应用程序是否可以修改的文件。
代码
public class FileDemo {
public static void main(String[] args) {
// File-->java.io包下的
String pathName = "D:/file/test1.txt";
// 创建File对象
File file = new File(pathName);
// 创建File对象
File file1 = new File("D:/java");
/**
* File判断方法
*/
// public boolean exists():测试此抽象路径名表示的文件或目录是否存在。
boolean exists = file.exists();
System.out.println(exists);
// public boolean isDirectory():测试此抽象路径名表示的文件是否为目录。如果给的是个假目录他则返回false
boolean directory = file.isDirectory();
System.out.println(directory);
// public boolean isFile():测试此抽象路径名表示的文件是否为普通文件。如果是返回true否则false,如果文件不存在则返回false
boolean file2 = file.isFile();
System.out.println(file2);
// public boolean isHidden():测试此抽象路径名命名的文件是否为隐藏文件。
boolean hidden = file.isHidden();
System.out.println(hidden);
// public boolean canRead():测试应用程序是否可以读取的文件。
boolean b = file.canRead();
System.out.println(b);
// public boolean canWrite():测试应用程序是否可以修改的文件。
boolean b1 = file.canWrite();
System.out.println(b1);
}
}
File的操作方法:
-
public boolean mkdir()
:创建由此路径名命名的目录。只能创建单级目录 -
public boolean mkdirs()
:创建由此路径名命名的目录,包括任何必要但不存在的父目录。也可以创建单级目录 -
public boolean createNewFile()
:当且仅当具有此名称的文件尚不存在时,以原子方式创建以此路径名命名的新的空文件。 -
public boolean delete()
:删除此抽象路径名表示的文件或目录。如果此路径名表示一个目录,则该目录必须为空才能被删除。 -
public boolean renameTo(File dest)
:移动文件,并且重命名 -
public String[] list()
:返回一个字符串数组,代表命此目录中所有的文件和目录。 -
public File[] listFiles()
:返回当前目录中的所有文件的File对象
代码
public class FileDemo {
public static void main(String[] args) throws IOException {
/**
* File的操作方法
*/
// public boolean mkdir():创建由此路径名命名的目录。只能创建单级目录
// boolean mkdir = file.mkdir();
// System.out.println(mkdir);
// public boolean mkdirs():创建由此路径名命名的目录,包括任何必要但不存在的父目录。也可以创建单级目录
// boolean mkdirs = file.mkdirs();
// System.out.println(mkdirs);
// public boolean createNewFile():当且仅当具有此名称的文件尚不存在时,以原子方式创建以此路径名命名的新的空文件。
boolean newFile = file.createNewFile();
System.out.println(newFile);
// public boolean delete():删除此抽象路径名表示的文件或目录。如果此路径名表示一个目录,则该目录必须为空才能被删除。
// boolean delete = file.delete();
// System.out.println(delete);
// public boolean renameTo(File dest):移动文件,并且重命名
boolean b2 = file.renameTo(new File("D:/newFileName"));
System.out.println(b2);
// public String[] list():返回一个字符串数组,代表命此目录中所有的文件和目录。
String[] list = file.list();
System.out.println(Arrays.toString(list));
// public File[] listFiles():返回当前目录中的所有文件的File对象
File[] files = file.listFiles();
// 删除此目录中的所有文件演示
for (File file3 : files) {
System.out.println(file3.getAbsolutePath());
// 删除文件
boolean delete = file3.delete();
// 打印是否删除成功
System.out.println(delete);
}
}
}
File类的过滤器
通过File的过滤器可以过滤文件,只查找某些我们想要的文件名称或后缀名称–>mp4/avi,查找后仅返回我们指定的文件类型或名称,可以是目录也可以是文件。
listFiles(filter)方法给他一个过滤对象查找出我们所需要的文件或目录。
-
使用listFiles(带参)实现
-
FileFilter
-
FilenameFilter
-
代码
public class FileDemo {
public static void main(String[] args) throws IOException {
/**
* 使用过滤器筛选我们需要查找的文件名称
*/
File file3 = new File("D:/file");
// 使用listFiles返回结果并且指定过滤器
File[] files1 = file3.listFiles(new FileFilter() {
@Override
// accept()方法用于过滤文件名称,返给我返回过滤后的文件
public boolean accept(File pathname) {
// return false代表这个文件不需要,直接过滤;返回true此文件需要
// 只返回我们需要用的文件
return pathname.getName().endsWith(".txt");
}
});
System.out.println(files1.length);
for (File file4 : files1) {
System.out.println(file4.getName());
}
// 自己验证
File[] files2 = file3.listFiles();
for (File file4 : files2) {
if (file4.getName().endsWith(".java")) {
System.out.println(file4.getName());
}
}
System.out.println("-------------------------------华丽的分割线-------------------------------");
// 第二种过滤方式
File file4 = new File("D:/file");
// 使用第二种方式过滤
File[] files3 = file4.listFiles(new FilenameFilter() {
@Override
// 用于过滤的方法,过滤我们需要的文件或者过滤不需要的文件
public boolean accept(File dir, String name) {
// !取反代表除.class后缀的文件全都输出
return !name.endsWith(".class");
}
});
// 打印过滤后的结果
for (File file5 : files3) {
System.out.println(file5.getName());
}
}
}
/*
public boolean mkdirs() {
// 验证文件或目录是否存在
if (exists()) {
return false;
}
// 创建单个目录
if (mkdir()) {
return true;
}
// 获取规范文件File信息
File canonFile = null;
try {
canonFile = getCanonicalFile();
} catch (IOException e) {
return false;
}
// getParentFile();获取创建目录的父级目录File实例
File parent = canonFile.getParentFile();
// 返回是否创建成功
return (parent != null && (parent.mkdirs() || parent.exists()) &&
canonFile.mkdir());
}
*/
8.递归算法
编程语言中方法调用自身就是递归,核心思想就是自己调用自己(间接或直接调用)
递归的使用:定义时以最简洁方式定义,相比循环简单多。
-
定义递归头部规则
-
什么时候才不会去调用自己本身,如果没有头部则代表是一个死循环调用
-
-
定义递归体
-
什么是需要调用自己本身
-
递归的缺点
-
容易出现栈内存溢出(占用过多的系统栈内存),如果当前深入层数过多则速度会变慢并且比for循环还慢,所以使用时一定一定要慎重,在要求高性能的程序中要尽量避免使用
递归的优点
-
递归非常简单简洁
使用递归遍历盘符中的所有文件
public class FileDemo {
public static void main(String[] args) throws IOException {
/**
* 调用递归遍历目录中所有的文件和目录
*/
recursionFile(new File("D:/"));
}
/**
* 定义递归方法
*
* @param file 文件类,代表当前是一个目录
*/
public static void recursionFile(File file) {
// 1. 首先获取当前目录中的所有文件
File[] files = file.listFiles();
// 判断files是否存在null的情况,如果null则直接return结束当前这一层方法
if (files != null) {
// return;
// 2. 循环files所有的文件与目录
for (File file1 : files) {
// 3. 定义规则,什么时候需要调用自己本身:只要当前是目录则调用自身
if (file1.isDirectory()) {
// 输出目录名称
System.out.println(file1.getAbsolutePath());
// 4. 如果是目录则调用自己本身,如果是目录则回调本身方法并将file1传入
recursionFile(file1);
} else {
// 如果不是目录则输出文件名称
System.out.println(file1.getAbsolutePath());
}
}
}
}
}