异常 1. 什么是异常? 程序运行期间 出现了不正常的现象。 异常/错误 2. 异常分类 编译时异常: IoException ParseException ClassNotFoundException CloneNotSupportedException 。。。。 运行时异常 (RuntimeException) NullPointerException---->NPE 3.处理异常 java语言提供异常处理机制 一段程序出现问题 不影响其他程序正常执行 3.1 捕获异常(真正处理异常的方式) try...catch...finally 何时使用finally? 释放物理资源/释放锁 try....finally 3.2 抛出异常 throws 在方法的签名后面使用throws抛出具体的异常类型 消极处理异常的方式 把异常抛出给调用 (没有能力处理的时候) 4. throw 产生异常。 在方法体里面 使用throw 抛出具体的异常对象。 throw new 异常类构造; 场景: 1. 预判 控制程序执行流程 2. 与自定义异常类的时候 3. 异常信息的传递 在catch Casued by lang包常用类 1. 整数缓存池是干吗的? 池子就是一个数组。 是一个包装类型的数据。 Byte Short Integer Long Character: -128-127 Character: 0-127 Integer num1 = 200;//自动装箱 Integer.valueOf(100) Integer num2 = 200; 2. 字符串与整数类型之间相互转换实现方式? int num = 100; num+""; String.valueOf(num) String str = "1234"; int s = Integer.parseInt(str) Long.parseLong(); 3. 比较对象一定要重写equlas+hashcode? == Object.equlas 4. Object.clone protected Object clone() throws CloneNotSupportedException; 5. 获得Class类对象的方式? getClass() Class.forName(); 类名.class; String VS StringBuffer vs StringBuilder 共同点: 都是代表任意一个字符串的数据。 不同点: 1.数据是否可变的角度。 String值不可变的。底层是由一个final byte[] StringBuffer/StringBuilder是可变的。执行任意更新功能 都会还原到源对象。 底层是由一个动态数组维护字符串数据。 2.性能不同。StringBuilder性能最高的 其次是String 最后是StringBuffer 3.安全角度分析。 StringBuffer是线程安全的一个类。底层的所有的功能都使用synchornized String: 线程安全的 StringBuilder: 线程不安全的 4. 从内存(拼接)。 StringBuffer/StringBuilder 永远只有1个变量 内存占用较少。 String: + concat join 都会产生很多个新的字符串数据 占用内存较多。 final vs finally vs finalize final:是一个修饰符 1.修饰变量 2、修饰类 3. 修饰方法 finally: 捕获异常。 try...catch...finally 当有资源需要释放。 finalize: 回收无用对象。不推荐手动调用。 GC会自动执行回收无用引用关联的对象。 可以回收软 弱 虚引用关联对象。
都是工具类。会用就可以了。
维护一个特定的日期时间。java.util.Date
//无参构造: 获得当前系统此刻日期时间 Date date = new Date(); System.out.println(date); Date(long date) //将指定的毫秒数转成特定的日期对象
@Data public class Employee { private Integer id; private String name; private String phone; private Date birthday; private Date hireDate; private Date createTime; private Date updateTime; @Override public String toString() { return "Employee{" + "id=" + id + ", name='" + name + '\'' + ", phone='" + phone + '\'' + ", birthday=" + DateUtil.dateConvertToStr(birthday) + ", hireDate=" + DateUtil.dateConvertToStr(hireDate) + ", createTime=" + DateUtil.dateConvertToStr(createTime) + ", updateTime=" + DateUtil.dateConvertToStr(updateTime) + '}'; } }
//员工入职: 录入员工信息到公司系统里面 //员工id name age phone 入职时间 生日 新建员工时间 更改员工信息时间 地址 public static void registerEmployee() { Scanner input = new Scanner(System.in); Employee employee = new Employee(); System.out.println("请录入员工name:"); employee.setName(input.nextLine()); System.out.println("请录入员工phone:"); employee.setPhone(input.nextLine()); //录入的字符串数据如何转换成一个Date类型的数据? //String 转 Date System.out.println("请录入员工生日:");//2020-01-01 12:00:00 String birthday = input.nextLine(); employee.setBirthday(DateUtil.strConvertDate(birthday)); System.out.println("请录入员工入职时间:");//2020-01-01 12:00:00 String hireDate = input.nextLine(); employee.setHireDate(DateUtil.strConvertDate(hireDate)); //System.out.println("请录入新建员工时间:"); //获得当前此刻的时间即可 employee.setCreateTime(new Date()); //能够获得一个完整的员工信息,用户体验感不高 //看不懂时间 //只能看懂: 2020-01-01 12:00:00 System.out.println("注册员工信息成功,信息如下:" + employee.toString()); input.close(); }
public static void test1() { //获得当前时间的毫秒数 Date date = new Date(); System.out.println(date.getYear() + 1900);//1900 System.out.println(date.getMinutes()); System.out.println(date.getHours()); System.out.println(date.getMonth() + 1);//2 System.out.println(date.getDate()); System.out.println(date.getDay());//1 获得这一天是这一周的第几天 System.out.println(date.getTime());//获得时间毫秒数 //不推荐使用Date里面的getTime获得毫秒数 //与对象密切相关 //推荐 System.out.println(System.currentTimeMillis());//毫秒数 System.out.println(System.nanoTime()); }
jdk1.8+ 在java.time.* 全部都是值不可变 任何更新都会产生新的对象 且线程都是安全的
Instant----> 年月日 时分秒
LocalDate 年月日
LocalTime 时分秒
LocalDateTime 年月日 时分秒
@Data public class UserInfo { private Integer id; private String name; private LocalDate birthday; private LocalDateTime hireDate; private LocalDateTime createTime; //local相关的对象转字符串 就调用这个类里面的format @Override public String toString() { return "UserInfo{" + "id=" + id + ", name='" + name + '\'' + ", birthday=" + birthday + ", createTime=" + createTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + '}'; } //从前到后: 客户端的数据转换后端的对象----> String转Date/localDate parse //从后往前: 给用户看的时候 ----->Date/localDate转String format }
private static void demo1() { Scanner input = new Scanner(System.in); UserInfo userInfo = new UserInfo(); System.out.println("请录入用户name:"); userInfo.setName(input.nextLine()); //String转LocalDate //字符串转jdk1.8+ time包里面的任意一个类 就使用这个类里面parse方法 System.out.println("请录入用户生日:"); String birthday = input.nextLine(); userInfo.setBirthday(LocalDate.parse(birthday)); System.out.println(userInfo.getBirthday()); //转: System.out.println("请录入用户入职时间:"); String hireDate = input.nextLine(); userInfo.setHireDate(LocalDateTime.parse(hireDate, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); //现在:now userInfo.setCreateTime(LocalDateTime.now());//获得的是当前此刻时间 System.out.println(userInfo.toString()); }
private static void demo2() { //1.获得LocalDateTime对象 //LocalDateTime now = LocalDateTime.now(); /* System.out.println(now);//2022-02-28T15:10:06.920312800 System.out.println(LocalDateTime.now(Clock.systemDefaultZone())); System.out.println(LocalDateTime.now(Clock.systemUTC())); //所有的时区都使用ZoneId代表 System.out.println(LocalDateTime.now(Clock.system(ZoneId.of("America/Chicago")))); //通过指定的时区获得时间,不太推荐local一些类 本地时间 System.out.println(ZonedDateTime.now(ZoneId.of("America/Chicago")));*/ //2020-10-01 12:30:30 LocalDateTime time = LocalDateTime.of(2022, Month.JANUARY, 1, 12, 30, 30); System.out.println(time); //值不可变 //TemporalAmount都是接口-----> Duration Period 时间间隔 // default Temporal plus(TemporalAmount amount) { //TemporalUnit: 时间单位 ChronoUnit //public static Duration of(long amount, TemporalUnit unit) { //time = time.plus(Period.ofYears(10)); //time = time.plus(10, ChronoUnit.YEARS); //time = time.plusYears(1); //time = time.minusMonths(2); LocalDateTime now = LocalDateTime.now(); //获得2个日期间隔的天数 //Temporal: 接口 代表日期时间 //TemporalUnit: 日期单位 //public long until(Temporal endExclusive, TemporalUnit unit) { long durationDays = Math.abs(now.until(time, ChronoUnit.DAYS)); System.out.println(durationDays); System.out.println(now.getMonthValue()); System.out.println(now.getMonth()); System.out.println(now.getDayOfWeek()); System.out.println(now.getDayOfMonth()); }
private static void demo3() { //1.获得Calendar 类对象 Calendar calendar = Calendar.getInstance();//多态 获得系统此刻日历信息 System.out.println(calendar); //获得具体时间单位数据----> get //Date date = calendar.getTime(); calendar转换成Date类对象 System.out.println(calendar.get(Calendar.YEAR)); // System.out.println(calendar.get(Calendar.MONTH)+1); // System.out.println(calendar.get(Calendar.DATE)); // System.out.println(calendar.get(Calendar.DAY_OF_MONTH)); // System.out.println(calendar.get(Calendar.HOUR)); // System.out.println(calendar.get(Calendar.MINUTE)); // System.out.println(calendar.get(Calendar.SECOND)); //修改年份值为2021 //年份-1 //calendar.set(Calendar.YEAR,calendar.get(Calendar.YEAR)-1); // calendar.set(Calendar.MONTH,Calendar.MAY); /* calendar.add(Calendar.YEAR,2); System.out.println(calendar.get(Calendar.YEAR)); System.out.println(calendar.get(Calendar.MONTH)+1);*/ //calendar.setTime(new Date());//将指定的date数据转换成Calander对象 //打印输出指定年份指定月份的完整的日历信息 //2022-02 //获得这个月份最大的天数 //calendar.set(Calendar.MONTH,Calendar.MARCH); int maximum = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); System.out.println(maximum); //周日 周一 //获得这一天是这一周的第几天 int day = calendar.get(Calendar.DAY_OF_WEEK); System.out.println(day); }
abstract class Format -----> java.text.Format
DateFormat , 格式化日期 SimpleDateFormat 子类 MessageFormat ,格式化字符数据 NumberFormat 格式化数字
public abstract class DateFormat extends Format
public class SimpleDateFormat extends DateFormat
常用构造: SimpleDateFormat(String pattern) 模式:
public class DateUtil { private DateUtil() { } private static final String PATTERN = "yyyy-MM-dd HH:mm:ss"; //String 转 Date public static Date strConvertDate(String dateStr) { Objects.requireNonNull(dateStr); if (dateStr.isBlank()) { throw new RuntimeException("字符串数据为空串"); } //转----> 使用日期格式化类转换数据 DateFormat dateFormat = new SimpleDateFormat(PATTERN); try { return dateFormat.parse(dateStr); } catch (ParseException e) { e.printStackTrace();//字符串时间无法满足pattern模式的要求(字符串时间内容>=pattern) } return null; } //Date转String public static String dateConvertToStr(Date date) { if (date == null) { return ""; } Objects.requireNonNull(date); DateFormat dateFormat = new SimpleDateFormat(PATTERN); return dateFormat.format(date); } }
SimpleDateFormat这个类线程不安全。不能作为成员变量使用、
DecimalFormat
DecimalFormat(String pattern)
private static void demo3() { //3.对钱数值进行格式化 double money = 16637743645556364353534535.6787346; System.out.println(money); NumberFormat numberFormat = new DecimalFormat(",###.###"); System.out.println(numberFormat.format(money)); //存储用户余额: 将钱全部转成分 //转成2部分: //在开发中 余额使用什么类型维护? BigDecimal---->小数运算 //System.out.println(0.1+0.2); //System.out.println(0.3/0.1); BigDecimal num1 = new BigDecimal("0.3"); BigDecimal num2 = new BigDecimal("0.1"); System.out.println(num1.divide(num2)); BigDecimal num3 = BigDecimal.valueOf(0.2); System.out.println(num3.add(num2)); } private static void demo2() { //2. 将数据转换成百分制的数字 小数点之后保留3个数字 double num = 0.1234567; NumberFormat numberFormat = new DecimalFormat(".###%"); String result = numberFormat.format(num); System.out.println(result); } private static void demo1() { //1. 保留小数点后面指定的位数 double num = 1100.567895; //System.out.println(Math.round(num)); //格式化数字类 NumberFormat //NumberFormat numberFormat = new DecimalFormat("0000000.000"); NumberFormat numberFormat = new DecimalFormat("######.###"); String result = numberFormat.format(num); System.out.println(result); //String转Double System.out.println(Double.parseDouble(result)); }
jdk1.8+提供的新的转换日期的格式化类。 这个类线程安全 且值不可变。
常用方法:
static DateTimeFormatter ofPattern(String pattern)
java.util.Random的java.util.Random是线程安全的。 但是,跨线程的同时使用java.util.Random实例可能会遇到争用,从而导致性能下降。 在多线程设计中考虑使用ThreadLocalRandom 。
Random() 创建一个新的随机数生成器。 Random(long seed) 使用单个 long种子创建一个新的随机数生成器。
private static void demo1() { ThreadLocalRandom random = ThreadLocalRandom.current(); int num = random.nextInt(1000, 10000); } private static void demo() { //循环5次 在每次循环里面获得5个随机数字 1000-10000 //预测到随机数是多少? 可以预测 指定seed for (int i = 1; i <= 5; i++) { Random random = new Random(1000); for (int j = 1; j <= 5; j++) { //获得随机数 int randomNum = (random.nextInt(9000) + 1000); System.out.print(randomNum + "\t"); } System.out.println(); } }
加密。 用户注册/路径/接口路径/参数 不能明文暴露。 必须密文传递/密文存储
解密。
http://book.zongheng.com/chapter/1182914/67622452.html https://read.qidian.com/chapter/YPMLlm2xwADH0qbqCO3QNg2/pk97yW9jK2dMs5iq0oQwLQ2/
是完全可逆。
//登录: 再加密 与加密之后数据进行比较 private static void demo2() { String pass = "MTIzNHpoYW5nc2FuJSQjQCE="; //1.获得Base64解码器 Base64.Decoder decoder = Base64.getDecoder(); byte[] bytes = decoder.decode(pass); //字节数组转String String s = new String(bytes); System.out.println(s); } //Base64是完全可逆的。 //加盐 private static final String SALT = "zhangsan%$#@!"; //模拟注册 private static void demo1() { String pass = "1234"; pass = pass + SALT; //Base64(使用一些字母和数字和特殊符号组成) //编码/加密----> 编码器 //1.获得编码器 Base64.Encoder encoder = Base64.getEncoder(); //2.对文本数据进行加密处理 //将字符串转换成字节数组 String encodePass = encoder.encodeToString(pass.getBytes()); System.out.println(encodePass);//MTIzNA== }
是一种不可逆的加密算法。信息摘要算法(MD5 SHA-1 SHA-256) Message-Digest Algorithm
1234====> 81dc9bdb52d04dc20036dbd8313ed055
将字符串转换成16进制字符组成的文本数据。
public class MD5Util { private MD5Util() { } public static String md5(String sourceStr) { Objects.requireNonNull(sourceStr); StringBuilder builder = new StringBuilder(); try { MessageDigest messageDigest = MessageDigest.getInstance("MD5"); messageDigest.update(sourceStr.getBytes()); byte[] bytes = messageDigest.digest(); for (byte aByte : bytes) { builder.append(byteToHex(aByte)); } } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return builder.toString().toUpperCase(); } private static final char[] array = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; private static String byteToHex(byte aByte) { int num = aByte; if (num < 0) { num += 256; } int low = num / 16; int high = num % 16; return array[low] + "" + array[high]; } }
1.1Date
1.2Calendar
特定的日历的时间。 抽象类
Calender类里的常用方法--set()/get()/setTime()/getTime()/add()
public class CalenderDemo { public static void main(String[] args) { //1.创建Calender对象 Calendar calendar = Calendar.getInstance(); //拿到系统当前此刻的日历时间 System.out.println(calendar); //2.获得具体时间单位的数据 get(int filed属性) 属性可用Calender类里的属性 System.out.println(calendar.get(Calendar.YEAR)); //2022 System.out.println(calendar.get(Calendar.MONTH)+1); //2 月份需要加1,才是当前月份 System.out.println(calendar.get(Calendar.DAY_OF_MONTH)); //27 System.out.println(calendar.get(Calendar.DATE)); //27 System.out.println(calendar.get(Calendar.DAY_OF_WEEK)); //1 这一周的第五天,国外周日是第一天 //3.与date的相互转换 //Calender转date 用的getTime(),返Date Date time = calendar.getTime(); System.out.println(time); //Sun Feb 27 12:27:50 CST 2022 //date转Calender 首先得有Date对象 然后还要有Calender实例 再用Calender的setTime(Date date)方法 Date date = new Date(); Calendar calendar1 = Calendar.getInstance(); calendar1.setTime(date); //4.修改时间 set方法 或者add方法 //使用set calendar.set(2020,Calendar.MONTH,1,12,30,30); //月份不要写死,想改成2月,就得写成1月。最好用其常量维护(1-12月份是0-11的标识) //之后查看日期,将变为修改后的日期 //add方法 add(int field,int amout) 现在要求从当前时间往后加10天 calendar.add(Calendar.DATE,10); //若用set去做,set(int field,int value) calendar.set(Calendar.DAY_OF_MONTH,calendar.get(Calendar.DAY_OF_MONTH)+10); } }
1.3LocalDate/LocalDateTime
员工信息
public class Emp { private Integer id; private LocalDate hireDate; //员工出生时间 private LocalDate birthday; //员工生日 private LocalDateTime create_time; //员工创建时间 private LocalDateTime update_time; //员工信息修改时间 }
LocalDate表示的年月日操作LocalDateTime时分秒
public class LocalDateDemo { public static void main(String[] args) { //LocalDate 用final修饰(没有子类),构造私有(不能new) 肯定用静态方法拿 //1.获得LocalDate实例 用LocalDate的静态方法,很多方法都返的实例 now() 或者 of LocalDate now = LocalDate.now(); System.out.println(now); //2022-02-27 获得当前时间 //of(年,月,日) 一个全是int,一个月是Month类(枚举类),推荐用常量去写,不要写死 LocalDate localDate = LocalDate.of(2022, Month.MAY, 1); System.out.println(localDate); //2022-05-01 //2.拿年,月,日 System.out.println(now.getYear()); //2022 System.out.println(now.getMonth()); //FEBRUARY 拿枚举的 System.out.println(now.getMonthValue()); //2 拿整型的 System.out.println(now.getDayOfMonth()); //27 //3.修改时间 plus加 minus减 now.plusDays(20); //这样做,不会加20天,值不可变。要想改变,要重新赋值 System.out.println(now); //2022-02-27 now = now.plusDays(20); //和String一样 System.out.println(now); //2022-03-19 //看plus带两参数的 plus(amountToAdd , TemporalUnit一个接口,用于限定) now = now.plus(20, ChronoUnit.DAYS); System.out.println(now); //2022-04-08 //plus带一个参的 plus(TemporalAmount一个接口,时间间隔) now = now.plus(Period.ofDays(20)); System.out.println(now); //2022-04-28 //4.求两个日期的时间间隔 until方法 //until(ChronoLocalDate) Period period = localDate.until(now); System.out.println(period); //P-3D (Y年 M月 D日) //until(Temporal ,TemporalUnit ) long days = now.until(localDate, ChronoUnit.DAYS); System.out.println(days); //3 } }
1.4 Instant
Instant 瞬时点
public class InstantDemo { public static void main(String[] args) { Instant now = Instant.now(); //拿的UTC(格林尼日时间)的时间,与中国时间差8小时 System.out.println(now); //2022-02-27T06:28:56.359890900Z //求中国时间 now = now.plus(Duration.ofHours(8)); //操作年月日用period 时分秒用Duration System.out.println(now); //2022-02-27T14:30:25.811234200Z //加时间 now = now.plusSeconds(Duration.ofHours(8).getSeconds()) ; //括号里是8小时转秒数 } }
2.1格式化日期类DateFormat
1.SimpleDateFormat
2.DateTimeFormatter
DateTimeFormatter格式化日期
@Data public class DateTimeFormatterDemo { private static final String PATTERN = "yyyy-MM-dd HH:mm:ss"; //创建时间格式 private static final DateTimeFormatter FORMATTER = DateTimeFormatter.ofPattern(PATTERN); public static void main(String[] args) { LocalDateTime localDateTime = LocalDateTime.now(); System.out.println(localDateTime); //2022-02-27T14:42:58.061979600 //不希望有T,和毫秒数,只要年月日和时分秒 //localDateTime 转String String format = FORMATTER.format(localDateTime); System.out.println(format); //2022-02-27 14:51:10 System.out.println("----------------------------------------"); //String转LocalDateTime String create_time = "2022-02-27 14:51:10"; Emp emp = new Emp(); //emp.setCreate_time(create_time); 这里不能直接转 //字符串转哪一个Local对象,就调用这个类里的parse方法 LocalDateTime localDateTime1 = LocalDateTime.parse(create_time,FORMATTER); //必须用parse()带两个参数的 emp.setCreate_time(localDateTime1); System.out.println(localDateTime1); //2022-02-27T14:51:10 System.out.println("============================================"); //String转LocalDate 也是parse,一个参两个参都行 String birthday = "2021-01-01"; emp.setBirthday(LocalDate.parse(birthday)); System.out.println(emp); } }
2.2格式化数字NumberFormat
一般针对小数和整数格式化,结果为字符串类型
何时用:1.保留小数点后几位 2.将小数转换成百分制 3.格式化钱数
public class DecimalDemo { public static void main(String[] args) { //保留两位小数 NumberFormat numberFormat = new DecimalFormat(".00"); //.##也可以 NumberFormat numberFormat1 = new DecimalFormat("00000.00"); //代表小数点前有5个数字 NumberFormat numberFormat2 = new DecimalFormat("#####.00"); double num = 100.56789; String result = numberFormat.format(num); //结果为字符串类型 System.out.println(result); //100.57 String result1 = numberFormat1.format(num); System.out.println(result1); //00100.57 不够用0填充 String result2 = numberFormat2.format(num); System.out.println(result2); //100.57 } }
public class DecimalDemo2 { public static void main(String[] args) { //百分数 在格式化对象时加个百分号即可 double num = 0.56789; NumberFormat numberFormat = new DecimalFormat(".##%"); //格式化对象 String result = numberFormat.format(num); System.out.println(result); //56.79% (四舍五入了) //格式化金钱 每三个一个逗号 若钱太大,还会从小数点分成两部分 double money = 18546546465.32165416565; NumberFormat numberFormat1 = new DecimalFormat("#,###.#### "); //格式化对象 String result1 = numberFormat1.format(money); System.out.println(result1); //18,546,546,465.3217 } }
ThreadLocalRadom 随机数 是Random的子类
public class RandomDemo { public static void main(String[] args) { for(int i=0;i<5;i++){ Random random = new Random(); //seed:当前纳秒数(时间会一直变) 无参 for(int j= 0;j<5;j++){ int num = random.nextInt(100); //产生0-100之间的随机整数,包头不包尾 System.out.print(num+","); } System.out.println(); } System.out.println("-----------------"); //伪随机:种子一致时,数值可预测 for(int i=0;i<5;i++){ Random random1 = new Random(100); //seed:100 有参 for(int j= 0;j<5;j++){ int num = random1.nextInt(100); //产生0-100之间的随机整数,包头不包尾 System.out.print(num+","); } System.out.println(); } ThreadLocalRandom random = ThreadLocalRandom.current(); int i = random.nextInt(1000, 10000); //拿1000-10000的随机数,包头不包尾 } }
编码: 加密 看的懂得数据转化成看不懂的数据 (路径,参数,基本信息)
解码: 解密 看不懂的数据转换成看得懂的数据
4.1Base64(1.8之后)
前台数据传输用的比较多
public class Base64Demo { private static final String ENCODING = "utf-8"; //加密规则 public static void main(String[] args) { //用户注册 对密码执行加密处理 userRegister(); //用户登录,对注册时加密的密码解码处理 //userLogin(); } private static boolean userLogin() { Scanner input = new Scanner(System.in); System.out.println("登录用户姓名:"); String name = input.next(); System.out.println("登录用户密码:"); String pass = input.next(); //登录时,系统会拿注册时的用户名和密码进行比对,假设已拿到 String regName = "admin"; String regPass = "MTIzNDU2"; //获得解码器 Base64.Decoder decoder = Base64.getDecoder(); byte[] decode = decoder.decode(regPass); //字节数组转字符串 String decodepass = new String(decode,Charset.forName(ENCODING)); if(!Objects.equals(regName,name) || !Objects.equals(decodepass,pass)){ return false; } return true; } private static void userRegister() { Scanner input = new Scanner(System.in); System.out.println("请录入用户姓名:"); //admin String name = input.next(); System.out.println("请录入用户密码:"); //123456 String pass = input.next(); //密文操作:对原密码加密处理 //获得编码器 Base64.Encoder encoder = Base64.getEncoder(); //开始编码 encodeToString(byte ) 需要字符串转字节数组 pass = encoder.encodeToString(pass.getBytes(Charset.forName(ENCODING ))); // name—pass String info = String.join("-",name,pass); System.out.println("用户注册成功,数据已经成功保存 "); System.out.println(info); //admin-MTIzNDU2 } }
4.2信息摘要算法 MessageDigest
抽象类,无子类,用静态方法实现
加密之后是16进制的字符串,该加密不可逆,无法破解。
public class MD5Util { private MD5Util(){ //构造私有化 } private static final String[] ARRAY = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"}; public static String md5EncodeStr(String sourceStr){ Objects.requireNonNull(sourceStr); StringBuilder builder = new StringBuilder(); try { //1.创建信息摘要的对象 MessageDigest messageDigest = MessageDigest.getInstance("MD5"); //括号里是加密规则,大小写不区分。检测括号里是否为加密规则,还是随意一个字符串,加一个try...catch... //2.更新加密 将源数据提交到加密规则中 messageDigest.update(sourceStr.getBytes(Charset.forName("utf-8"))); //3.加密操作 byte[] bytes = messageDigest.digest(); //4.字节转字符串 //System.out.println("加密之后的数据:" + new String(bytes, Charset.forName("utf-8"))); //将每个字节转换成16进制数据,再拼接成字符串 //16进制从0-F 一个字节占8个二进制位 一个16进制数字占4个二进制位 //字节转16进制,一个字节要换成两个16进制内容 //高低位 for(byte aByte:bytes){ builder.append(byteToHexStr(aByte)); } } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return builder.toString(); } private static String byteToHexStr(byte aByte) { int num = aByte; //先转为整型 if(num<0){ //aByte是小数,则补码 num+=256; } //高位和低位的运算 int lowIndex = num%16; int highIndex = num/16; return ARRAY[highIndex]+ARRAY[lowIndex]; } public static void main(String[] args) { System.out.println(md5EncodeStr("1234")); } }
public class MD5Util { private MD5Util(){ //构造私有化 } private static final String[] ARRAY = {"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"}; public static String md5EncodeStr(String sourceStr){ Objects.requireNonNull(sourceStr); try { //1.创建信息摘要的对象 MessageDigest messageDigest = MessageDigest.getInstance("MD5"); //括号里是加密规则,大小写不区分。检测括号里是否为加密规则,还是随意一个字符串,加一个try...catch... //2.更新加密 将源数据提交到加密规则中 messageDigest.update(sourceStr.getBytes(Charset.forName("utf-8"))); //3.加密操作 byte[] bytes = messageDigest.digest(); //4.字节转字符串 //System.out.println("加密之后的数据:" + new String(bytes, Charset.forName("utf-8"))); //将每个字节转换成16进制数据,再拼接成字符串 //16进制从0-F 一个字节占8个二进制位 一个16进制数字占4个二进制位 //字节转16进制,一个字节要换成两个16进制内容 //高低位 BigInteger bigInteger = new BigInteger(1,bytes); //调用number的一个子类 1代表将字节数组转成一个正整数 return bigInteger.toString(16); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return null; } public static void main(String[] args) { System.out.println(md5EncodeStr("1234")); } }
public class DateUtil { private DateUtil() { } //SimpleDateFormat作为全局变量使用,在单线程里面没有任何问题。但在并发里SimpleDateFormat是一个线程不安全的一个类 //内存:局部的时候 会new很多次 占据很多堆内存 //线程安全 解决内存过多问题 使用全局进行解决 在单线程没有问题的 在并发里面就会并发安全的问题 //性能 使用synchronized解决了线程安全以及内存占据过多的问题 但是性能就很低 //后期使用ThreadLocal,会完美解决 //现在SimpleDateFormat还是作为局部变量去用吧 private static final String PATTERN = "yyyy-MM-dd HH:mm:ss"; //String 转 Date dateFormat.parse() public static Date strConvertDate(String dateStr) { Objects.requireNonNull(dateStr); //要求不为null if (dateStr.isBlank()) { //要求不是空字符串 throw new RuntimeException("字符串数据为空串"); } DateFormat dateFormat = new SimpleDateFormat(PATTERN); //转----> 使用日期格式化类转换数据 try { return dateFormat.parse(dateStr); } catch (ParseException e) { e.printStackTrace(); //字符串时间无法满足pattern模式的要求(字符串时间内容>=pattern) } return null; } //Date转String dateFormat.format() public static String dateConvertToStr(Date date) { if (date == null) { return ""; } Objects.requireNonNull(date); DateFormat dateFormat = new SimpleDateFormat(PATTERN); return dateFormat.format(date); } }
@Data public class Employee { private Integer id; private String name; private String phone; private Date birthday; private Date hireDate; private Date createTime; private Date updateTime; @Override public String toString() { return "Employee{" + "id=" + id + ", name='" + name + '\'' + ", phone='" + phone + '\'' + ", birthday=" + DateUtil.dateConvertToStr(birthday) + ", hireDate=" + DateUtil.dateConvertToStr(hireDate) + ", createTime=" + DateUtil.dateConvertToStr(createTime) + ", updateTime=" + DateUtil.dateConvertToStr(updateTime) + '}'; } }
public class DateDemo { public static void main(String[] args) { //无参构造: 获得当前系统此刻日期时间 //Date date = new Date(); //System.out.println(date); //registerEmployee(); /* new Thread(DateDemo::test).start(); new Thread(DateDemo::test).start(); new Thread(DateDemo::test).start(); new Thread(DateDemo::test).start();*/ test1(); } public static void test1() { //获得当前时间的毫秒数 Date date = new Date(); System.out.println(date.getYear() + 1900); //从1900年开始算起 System.out.println(date.getMinutes()); System.out.println(date.getHours()); System.out.println(date.getMonth() + 1); //2 System.out.println(date.getDate()); System.out.println(date.getDay()); //1 获得这一天是这一周的第几天 System.out.println(date.getTime()); //获得时间毫秒数 //不推荐使用Date里面的getTime获得毫秒数,与对象密切相关 //推荐 System.out.println(System.currentTimeMillis()); //毫秒数 System.out.println(System.nanoTime()); //纳秒数 } public static void test() { String[] dateStrArray = { "2020-01-01 12:00:00", "2020-01-01 12:00:00", "2020-01-01 12:00:00", "2020-01-01 12:00:00", "2020-01-01 12:00:00", "2020-01-01 12:00:00", "2020-01-01 12:00:00", "2020-01-01 12:00:00", "2020-01-01 12:00:00", "2020-01-01 12:00:00", "2020-01-01 12:00:00", "2020-01-01 12:00:00", "2020-01-01 12:00:00", "2020-01-01 12:00:00", "2020-01-01 12:00:00"}; //将数组里面所有的字符串都解析成Date类型的数据 for (String str : dateStrArray) { System.out.println(DateUtil.strConvertDate(str)); } } //员工入职: 录入员工信息到公司系统里面 //员工id name age phone 入职时间 生日 新建员工时间 更改员工信息时间 地址 public static void registerEmployee() { Scanner input = new Scanner(System.in); Employee employee = new Employee(); System.out.println("请录入员工name:"); employee.setName(input.nextLine()); System.out.println("请录入员工phone:"); employee.setPhone(input.nextLine()); //录入的字符串数据如何转换成一个Date类型的数据? //String 转 Date System.out.println("请录入员工生日:");//2020-01-01 12:00:00 String birthday = input.nextLine(); employee.setBirthday(DateUtil.strConvertDate(birthday)); System.out.println("请录入员工入职时间:");//2020-01-01 12:00:00 String hireDate = input.nextLine(); employee.setHireDate(DateUtil.strConvertDate(hireDate)); //System.out.println("请录入新建员工时间:"); //获得当前此刻的时间即可 employee.setCreateTime(new Date()); //能够获得一个完整的员工信息,用户体验感不高 //看不懂时间 //只能看懂: 2020-01-01 12:00:00 System.out.println("注册员工信息成功,信息如下:" + employee.toString()); input.close(); } }
@Data public class UserInfo { private Integer id; private String name; private String pass; private LocalDate birthday; private LocalDateTime hireDate; private LocalDateTime createTime; //local相关的对象转字符串 就调用这个类里面的format @Override public String toString() { return "UserInfo{" + "id=" + id + ", name='" + name + '\'' + ", pass='" + pass + '\'' + ", birthday=" + birthday + ", createTime=" + createTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + '}'; } //从前到后: 客户端的数据转换后端的对象----> String转Date/localDate parse //从后往前: 给用户看的时候 ----->Date/localDate转String format }
public class LocalDemo { public static void main(String[] args) { //获得当前此刻时间 //System.out.println(LocalDateTime.now().toString()); //System.out.println(LocalDate.now()); //System.out.println(LocalTime.now()); //System.out.println(Instant.now()); //与中国差8小时 UTC 英国格林尼治时间 demo3(); } private static void demo3() { //1.获得Calendar 类对象 (jdk1.8之前就有了,日历类) Calendar calendar = Calendar.getInstance(); //多态 获得系统此刻日历信息 System.out.println(calendar); //获得具体时间单位数据----> get //Date date = calendar.getTime(); calendar转换成Date类对象 System.out.println(calendar.get(Calendar.YEAR)); //System.out.println(calendar.get(Calendar.MONTH)+1); //System.out.println(calendar.get(Calendar.DATE)); //System.out.println(calendar.get(Calendar.DAY_OF_MONTH)); //System.out.println(calendar.get(Calendar.HOUR)); //System.out.println(calendar.get(Calendar.MINUTE)); //System.out.println(calendar.get(Calendar.SECOND)); //修改年份值为2021 //年份-1 //calendar.set(Calendar.YEAR,calendar.get(Calendar.YEAR)-1); //calendar.get(Calendar.YEAR) 拿当前年份 //calendar.set(Calendar.MONTH,Calendar.MAY); //变成5月 /* calendar.add(Calendar.YEAR,2); //加两年 System.out.println(calendar.get(Calendar.YEAR)); System.out.println(calendar.get(Calendar.MONTH)+1);*/ //calendar.setTime(new Date()); //将指定的date数据转换成Calander对象 //打印输出指定年份指定月份的完整的日历信息 比如:2022-02 //calendar.set(Calendar.MONTH,Calendar.MARCH); //拿2月 (底层的月份从1月到12月,是0-11的序号。拿2月,就得MARCH) int maximum = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); //获得这个月份最大的天数 System.out.println(maximum); //周日 周一 int day = calendar.get(Calendar.DAY_OF_WEEK); //获得这一天是这一周的第几天 System.out.println(day); } private static void demo2() { //1.获得LocalDateTime对象 //LocalDateTime now = LocalDateTime.now(); /* System.out.println(now); //2022-02-28T15:10:06.920312800 System.out.println(LocalDateTime.now(Clock.systemDefaultZone())); System.out.println(LocalDateTime.now(Clock.systemUTC())); //所有的时区都使用ZoneId代表 System.out.println(LocalDateTime.now(Clock.system(ZoneId.of("America/Chicago")))); //通过指定的时区获得时间,不太推荐local一些类 本地时间 System.out.println(ZonedDateTime.now(ZoneId.of("America/Chicago")));*/ //2020-10-01 12:30:30 LocalDateTime time = LocalDateTime.of(2022, Month.JANUARY, 1, 12, 30, 30); System.out.println(time); //TemporalAmount是接口(时间间隔)----->两个实现类: Duration Period // default Temporal plus(TemporalAmount amount) -------plus带一个参数的 //TemporalUnit是接口(时间单位) 实现类:ChronoUnit //public static Duration of(long amount, TemporalUnit unit) Duration的有参构造 //time包里的类,值不可变,要想改变,重新创建赋值 //time = time.plus(Period.ofYears(10)); (用TemporalAmount的Period实现类,Duration不让用) //time = time.plus(10, ChronoUnit.YEARS); //加10年 //time = time.plusYears(1); //time = time.minusMonths(2); //减2个月 LocalDateTime now = LocalDateTime.now(); //获得2个日期间隔的天数 用until(); //Temporal: 接口 代表日期时间 string是其一个实现类的返回值,故这里可写字符串 //TemporalUnit: 日期单位 //public long until(Temporal endExclusive, TemporalUnit unit) long durationDays = Math.abs(now.until(time, ChronoUnit.DAYS)); //加绝对值不用考虑正负 System.out.println(durationDays); System.out.println(now.getMonthValue()); //拿月,返回int类型 System.out.println(now.getMonth()); //拿月,返回Month枚举类 System.out.println(now.getDayOfWeek()); //这一周的第几天(欧美是周日为一周的第一天) System.out.println(now.getDayOfMonth()); } private static void demo1() { Scanner input = new Scanner(System.in); UserInfo userInfo = new UserInfo(); System.out.println("请录入用户name:"); userInfo.setName(input.nextLine()); //String转LocalDate //字符串转jdk1.8+ time包里面的任意一个类 就使用这个类里面parse方法 System.out.println("请录入用户生日:"); String birthday = input.nextLine(); userInfo.setBirthday(LocalDate.parse(birthday)); System.out.println(userInfo.getBirthday()); //转: System.out.println("请录入用户入职时间:"); String hireDate = input.nextLine(); userInfo.setHireDate(LocalDateTime.parse(hireDate, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"))); //现在:now userInfo.setCreateTime(LocalDateTime.now());//获得的是当前此刻时间 System.out.println(userInfo.toString()); } }
public class NumberFormatDemo { public static void main(String[] args) { demo3(); } private static void demo3() { //3.对钱数值进行格式化 (金钱的整数部分,每三位一个逗号) double money = 16637743645556364353534535.6787346; System.out.println(money); NumberFormat numberFormat = new DecimalFormat(",###.###"); System.out.println(numberFormat.format(money)); //存储用户余额: // 法一:将钱全部转成分,再用long类型存 //法二:分成2部分(用小数点分),分别用long或double存,再拼接 //在开发中,余额使用什么类型维护? BigDecimal---->小数运算(不丢失任意精度) //System.out.println(0.1+0.2); //System.out.println(0.3/0.1); 2.9999999 会丢失精度 BigDecimal num1 = new BigDecimal("0.3"); BigDecimal num2 = new BigDecimal("0.1"); System.out.println(num1.divide(num2)); //不会丢失精度 divide除 BigDecimal num3 = BigDecimal.valueOf(0.2); System.out.println(num3.add(num2)); //add加 } private static void demo2() { //2. 将数据转换成百分制的数字 小数点之后保留3个数字 double num = 0.1234567; NumberFormat numberFormat = new DecimalFormat(".###%"); String result = numberFormat.format(num); System.out.println(result); } private static void demo1() { //1. 保留小数点后面指定的位数 double num = 1100.567895; //格式化数字类 NumberFormat //NumberFormat numberFormat = new DecimalFormat("0000000.000"); NumberFormat numberFormat = new DecimalFormat("######.###"); String result = numberFormat.format(num); System.out.println(result); //String转Double Double.parseDouble(); System.out.println(Double.parseDouble(result)); } }
public class RandomDemo { public static void main(String[] args) { //System.out.println(Math.random());//0.0-1.0 这个是Manth类里 demo1(); } private static void demo1() { //用random的子类ThreadLocalRandom,更好用,两者都线程安全,但并发里,ThreadLocalRandom性能更好 ThreadLocalRandom random = ThreadLocalRandom.current(); int num = random.nextInt(1000, 10000); //1000-10000,方法也比Random好用 } private static void demo() { //循环5次 在每次循环里面获得5个随机数字 1000-10000 //预测到随机数是多少? 可以预测 指定seed //如下为伪随机 for (int i = 1; i <= 5; i++) { Random random = new Random(1000); //若将其拿出循环,和Random()不带参一样无法预测 for (int j = 1; j <= 5; j++) { //获得随机数 int randomNum = (random.nextInt(9000) + 1000); //1000-10000 System.out.print(randomNum + "\t"); } System.out.println(); } } }
public class PassDemo { public static void main(String[] args) { System.out.println(MD5Util.md5("1234")); } private static void md5() { String pass = "1234"; try { //1.获得信息摘要对象 MessageDigest messageDigest = MessageDigest.getInstance("MD5"); //2.更新摘要算法---->将要加密的文本数据传输到算法中 pass = pass + SALT; //加盐,MD5不可逆,加盐是有效的 messageDigest.update(pass.getBytes()); //3.执行加密操作 byte[] bytes = messageDigest.digest(); //将字节数组里面的每个字节数据转换成对应的16进制的字符 //一个字节数据可以转成几个16进制内字符数据? 一个字节8bit,一个16进制的字符4bit //一个字节----> 转换成2个16进制的字符 //字节数组里的每个字节数据转成对应的16进制的字符 手写如下: /* StringBuilder builder = new StringBuilder(); for (byte aByte : bytes) { int num = aByte; if (num < 0) { num += 256; } int low = num / 16; int high = num % 16; builder.append(array[low]).append(array[high]); } System.out.println(builder);*/ //法二:BigInteger String s = new BigInteger(1, bytes).toString(16); //1标识为正,不懂看底层 System.out.println(s); //81dc9bdb52d04dc20036dbd8313ed055 } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } } //16进制里面字符数据是固定 0-F //0-15 static char[] array = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; //登录: 将登录时密码也加密,与注册时加密的密码进行比较(现实中多用此方法) //或者将注册时的密码解密,与登录时的密码比较 private static void demo2() { String pass = "MTIzNHpoYW5nc2FuJSQjQCE="; //1.获得Base64解码器 Base64.Decoder decoder = Base64.getDecoder(); byte[] bytes = decoder.decode(pass); //字节数组转String String s = new String(bytes); System.out.println(s); } //Base64是完全可逆的。(可以破解) //加盐,为避免破解,提高安全性的一种操作。只针对不可逆的加密算法,对Base64无效,下面流程只是感受下 private static final String SALT = "zhangsan%$#@!"; //模拟注册 private static void demo1() { String pass = "1234"; //密码 pass = pass + SALT; //加盐 //Base64(使用一些字母和数字和特殊符号组成) //编码/加密----> 编码器 //1.获得编码器 Base64.Encoder encoder = Base64.getEncoder(); //2.对文本数据进行加密处理 //将字符串转换成字节数组 String encodePass = encoder.encodeToString(pass.getBytes()); System.out.println(encodePass); //MTIzNA== } }
public class MD5Util { private MD5Util() { } public static String md5(String sourceStr) { Objects.requireNonNull(sourceStr); StringBuilder builder = new StringBuilder(); try { MessageDigest messageDigest = MessageDigest.getInstance("MD5"); //获得信息摘要对象 messageDigest.update(sourceStr.getBytes()); //更新摘要算法,要加密的文件数据传到算法中 byte[] bytes = messageDigest.digest(); //加密 for (byte aByte : bytes) { builder.append(byteToHex(aByte)); } } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } return builder.toString().toUpperCase(); } private static final char[] array = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; private static String byteToHex(byte aByte) { //字节数组里的每个字节数据转成对应的16进制的字符 int num = aByte; if (num < 0) { num += 256; } int low = num / 16; int high = num % 16; return array[low] + "" + array[high]; } }
public class Exercise1 { public static void main(String[] args) { demo1(); //(jdk1.8之前) demo2(); //(jdk1.8之后) } private static void demo2() { LocalDateTime localDateTime = LocalDateTime.of(2022,Calendar.FEBRUARY,1,12,0,0); DateTimeFormatter formatter = DateTimeFormatter.ofPattern(PATTERN); String format = formatter.format(localDateTime); System.out.println(format); //String format1 = localDateTime.format(formatter); } private static final String PATTERN = "yyyy-MM-dd HH:mm:ss"; private static void demo1() { //Date转String //1.创建Date对象 Date date = new Date(); //获得系统当前时间 long time = date.getTime(); //获得毫秒数(不推荐) long millis = System.currentTimeMillis(); //推荐 //创建Calender对象 Calendar calendar = Calendar.getInstance(); calendar.set(2022,Calendar.FEBRUARY,1,12,0,0); //2022-2-1 12:00:00 //Calender转Date Date date1 = calendar.getTime(); //2.创建格式类DateFormat DateFormat dateFormat = new SimpleDateFormat(PATTERN); String dateStr = dateFormat.format(date); System.out.println(dateStr); } }
public class Exercise2 { public static void main(String[] args) { //demo3(); demo4(); } private static void demo4() { //动态月份的情况 int year = 2022; Scanner input = new Scanner(System.in); System.out.println("请录入月份:"); int month = input.nextInt(); Calendar calendar = Calendar.getInstance(); calendar.set(year,month-1,1); System.out.println("日\t一\t二\t三\t四\t五\t六"); int totalDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); //判断1号有几个空格 int day = calendar.get(Calendar.DAY_OF_WEEK); for (int i = 1; i < day; i++) { System.out.print("\t"); } for (int i = 1; i <= totalDay; i++) { System.out.print(i+"\t"); //判断当前天是否为一周最后一天,是则换行 calendar.set(Calendar.DAY_OF_MONTH,i); if (calendar.get(Calendar.DAY_OF_WEEK)==7){ System.out.println(); } } } private static void demo3() { //固定月份的情况 int year = 2022; int month = 2; Calendar calendar = Calendar.getInstance(); calendar.set(year,month-1,1); //2月份的序号是1 System.out.println("日\t一\t二\t三\t四\t五\t六"); int totalDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); System.out.print("\t\t"); for (int i = 1; i <= totalDay; i++) { System.out.print(i+"\t"); //判断当前天是否为一周最后一天,是则换行 calendar.set(Calendar.DAY_OF_MONTH,i); if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY){ System.out.println(); } } } }
public class Exercise4 { public static void main(String[] args) { //demo1(); demo2(); } private static void demo2() { //LocalDateTime 与 LocalDateTime LocalDateTime dateTime1 = LocalDateTime.of(2022,Calendar.FEBRUARY,1,12,0,0); LocalDateTime dateTime2 = LocalDateTime.now(); long hours = dateTime1.until(dateTime2, ChronoUnit.HOURS); //括号里的减括号外面的 System.out.println(hours); } private static void demo1() { //Date 与 Date Calendar calendar = Calendar.getInstance(); calendar.set(2022,Calendar.FEBRUARY,1,12,0,0); //2022-2-1 12:00:00 Date date1 = calendar.getTime(); Date date2 = new Date(); long result = Math.abs((date1.getTime()-date2.getTime())/1000/3600); System.out.println(result); } }
public class Exercise5 { public static void main(String[] args) { demo1(new Date(),10); //Date之间的操作 demo2(LocalDate.now(),10); //LocalDate之间的操作 } private static LocalDate demo2(LocalDate localDate,int days) { return localDate.plusDays(days); } private static Date demo1(Date date,int days) { //传入时间加时间间隔 //用毫秒数来写 long time = date.getTime() + Duration.ofDays(days).toMillis(); //加号后面的是天转毫秒 return new Date(time); } }
public class Exercise6 { public static void main(String[] args) { demo1(); //demo2(); } private static void demo2() { StringBuilder builder = new StringBuilder(); ThreadLocalRandom random = ThreadLocalRandom.current(); int choice = random.nextInt(0,3); for (int i = 1; i <= 5; i++) { char ch = ' '; switch (choice) { case 0: ch = (char)random.nextInt(48,57); break; case 1: ch = (char)random.nextInt(68,90); break; case 2: ch = (char)random.nextInt(97,122); break; } builder.append(ch); } System.out.println(builder.toString()); } private static void demo1() { //48-57 0-9 A-Z 65-90 a-z 97-122 ThreadLocalRandom random = ThreadLocalRandom.current(); StringBuilder builder = new StringBuilder(); int count = 5; for(int i=1;i<=count;i++){ int num = random.nextInt(48,122); if(num>=48 && num<=57){ num = num -48; //直接变成对应数字 builder.append(num); }else if( (num>=65 && num<=90) || (num>=97 && num<=122) ){ char ch = (char)num; //数字转字符 builder.append(ch); }else { i--; } } System.out.println(builder.toString()); } }
public class ExerciseDemo { public static void main(String[] args) { //System.out.println(demo5(new Date(), 10)); demo6(); }
private static void demo6() { //6. 要求写一个工具类,可以自定义获取N个随机数字或字母(0~9,a~z,A~Z混合一起) StringBuilder code = new StringBuilder(); ThreadLocalRandom random = ThreadLocalRandom.current(); //ASCII //0~9 48-57 //A~Z 65-90 //a~z 97-122 for (int i = 0; i < 6; i++) { int num = random.nextInt(48, 123); if ((num > 57 && num < 65) || (num > 90 && num < 97)) { i--; continue; } code.append((char) num); } System.out.println("验证码:" + code); }
private static Date demo5(Date date, int day) { //LocalDate的使用场景 //1. 修饰属性 //2. 每天创建新的目录 以当前时间为目录名称 String string = LocalDate.now().toString(); LocalDate localDate = LocalDate.now(); localDate = localDate.plusDays(10); System.out.println(localDate); //5. 一个方法,要求传入时间和间隔天数,返回新的日期 //将day的数据运算到date时间当 //date+day /*long time1 = date.getTime(); long millis = Duration.ofDays(day).toMillis(); date.setTime(time1 + millis);*/ //使用Calendar Calendar calendar = Calendar.getInstance(); calendar.setTime(date); calendar.add(Calendar.DATE, day); return calendar.getTime(); }
private static void demo4() { LocalDate localDate1 = LocalDate.now();//3-1 LocalDate localDate2 = LocalDate.of(2021, Month.MARCH, 2);//3-2 long days = Math.abs(localDate1.until(localDate2, ChronoUnit.DAYS)); System.out.println(Duration.ofDays(days).toHours()); /*Period period = localDate2.until(localDate1); System.out.println(period.toString()); System.out.println(period.getYears()); System.out.println(period.getMonths()); System.out.println(period.getDays());*/ }
private static void demo3() { //3. 从命令行输入一个字符串!要求从中随机选择6个字符组成验证码 String str = "ehret76235423lldshge723656325gfds"; //随机获得6个字符 //Random---->ThreadLocalRandom ThreadLocalRandom random = ThreadLocalRandom.current(); //获得字符串里面的一个字符数据 char charAt(int index); StringBuilder code = new StringBuilder(); for (int i = 0; i < 6; i++) { //随机是字符的索引值 index>=0 index private static void demo2() { //2. 使用Calendar类的相关属性以及方法!打印出某年某个月的日历信息!(要求年月日由命令行输入) int year = 2022; int month = Calendar.MARCH; //Calendar类里面常用的功能方法 //1.Calendar getInstance(); 获得Calender类对象 //2.long get(int field); 拿年/月/日 //3. void set(int field,int newValue); 修改年份 //4. void add(int field,int duration); 增加年份 Calendar calendar = Calendar.getInstance(); /* calendar.set(Calendar.YEAR,year); calendar.set(Calendar.MONTH,month); calendar.set(Calendar.DAY_OF_MONTH,1);*/ calendar.set(year, month, 1); System.out.println("日\t1\t2\t3\t4\t5\t6"); //1.1 获得指定月份的总天数 int totalDay = calendar.getActualMaximum(Calendar.DAY_OF_MONTH); //1.2 获得指定月份1号属于这一周的第几天 int num = calendar.get(Calendar.DAY_OF_WEEK); for (int i = 1; i < num; i++) { System.out.print("\t"); } for (int day = 1; day <= totalDay; day++) { //一周就7天 换行 判断一下这一天是否是这一周的最后一天 System.out.print(day + "\t"); calendar.set(Calendar.DATE, day); if (calendar.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) { System.out.println(); } } }private static void demo1() { //1.将Date转换成String //1.1 创建pattern StringBuilder pattern = new StringBuilder("yyyy-MM-dd HH:mm:ss a E"); //1.2 创建Date对象 //Date类常用构造方法: new Date() new Date(long time) (这里是毫秒数) Date date = new Date(); //1.3 创建格式化日期对象 //Format---> // DateFormat---->SimpleDateFormat // NumberFormat---->DecimalFormat DateFormat dateFormat = new SimpleDateFormat(pattern.toString()); //1.4 转换 String result = dateFormat.format(date); System.out.println(result); //2.LocalDateTime转换成String //2.1 创建LocalDateTime对象 LocalDateTime now = LocalDateTime.now(); System.out.println(now);//2022-03-01T09:44:17.159568100 System.out.println(now.format(DateTimeFormatter.ofPattern(pattern.toString()))); } }