day04 【日期与数组工具类】 第一章 包装类 Java中的8种基本数据类型还不是对象,所以要把它们变成对象,变成对象之后,可以提供一些方法对数据进行操作。
//把基本类型的数据包装成对象
1.1 概念 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class BaoZhuang { public static void main (String[] args) { ArrayList<Integer> list = new ArrayList <>(); list.add(100 ); list.add(200 ); list.add(300 ); list.add(500 ); for (int i = 0 ; i < list.size(); i++) { int num = list.get(i); System.out.println(num); } } }
1.2 Integer类对象的创建 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
核心补充:Integer 的「缓存机制」(面试常考)
这是 new Integer() 和 Integer.valueOf() 最关键的区别:
new Integer(int value) :每次都会创建一个新的对象 ,即使值相同。
Integer.valueOf(int i) :会先检查值是否在 -128 到 127 之间(默认缓存范围),如果在,直接返回缓存池中的已有对象 ;如果不在,才创建新对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 Integer a = new Integer (100 );Integer b = new Integer (100 );System.out.println(a == b); Integer c = Integer.valueOf(100 );Integer d = Integer.valueOf(100 );System.out.println(c == d); Integer e = Integer.valueOf(200 );Integer f = Integer.valueOf(200 );System.out.println(e == f);
1.3 Integer类的常用方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 public class Demo04IntegerMethod { public static void main (String[] args) { System.out.println(Integer.MAX_VALUE); System.out.println(Integer.MIN_VALUE); int num = 100 ; System.out.println(Integer.toBinaryString(num)); System.out.println(Integer.toOctalString(num)); System.out.println(Integer.toHexString(num)); } }
1.4 包装类的自动装箱拆箱
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 public class Test02_1 { public static void main (String[] args) { Integer i1 = new Integer (123 ); System.out.println(i1); Integer i2 = Integer.valueOf(345 ); System.out.println(i2); Integer i3 = 456 ; System.out.println(i3); int i4 = i1.intValue(); int i5 = i2; System.out.println(i4); System.out.println(i5); } }
1.5 基本类型转换成对应的字符串 在开发中,经常使用包装类对字符串和基本类型数据进行相互转换。
把字符串转换为数值型数据:包装类.parseXxx(字符串)
1 2 public static int parseInt (String s) 把字符串转换为基本数据类型
将数值型数据转换为字符串:包装类.valueOf(数据);
1 2 public static String valueOf (int a) 把基本类型数据转换为字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public class Demo06ToString { public static void main (String[] args) { int num = 20 ; String strNum = num + "" ; System.out.println(strNum); System.out.println(strNum+20 ); String s = String.valueOf(num); System.out.println(s); System.out.println(s+20 ); String s2 = Integer.toString(num); System.out.println(s2); System.out.println(s2+20 ); } }
1.6 String解析成对应的基本类型 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class Demo07ParseString { public static void main (String[] args) { String str = "20" ; int num = Integer.parseInt(str); System.out.println(num); System.out.println(num + 20 ); String str2 = "66.66" ; double num2 = Double.parseDouble(str2); System.out.println(num2); System.out.println(num2 + 33.33 ); String str3 = "true" ; boolean reslut = Boolean.parseBoolean(str3); System.out.println(reslut); System.out.println(!reslut); } }
1.7案例 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 public class Test02_2 { public static void main (String[] args) { String s1 = String.valueOf(123 ); System.out.println(s1 instanceof String); int i = Integer.parseInt(s1); System.out.println(++i); System.out.println(Integer.MAX_VALUE); System.out.println(Integer.MIN_VALUE); } } public class Test { public static void main (String[] args) { String s = "22,1,555,128,44,77,99,25,6,888,111" ; String[] arr = s.split("," ); int [] arr2 = new int [arr.length]; for (int i = 0 ; i < arr.length; i++) { arr2[i] = Integer.parseInt( arr[i]); } Arrays.sort(arr2); String string = Arrays.toString(arr2); System.out.println(string); } }
Date类 Date类,Java中是由这个类的对象 用来表示日期或者时间。
Date对象记录的时间是用毫秒值 来表示的。
Java语言规定,1970年1月1日0时0分0秒认为是时间的起点 ,此时记作0,那么1000(1秒=1000毫秒)就表示1970年1月1日0时0分1秒,依次内推。
下面是Date类的构造方法,和常见的成员方法
使用new Date(),这将创建一个代表当前时间的Date对象 。 使用new Date(long millis),通过传递一个毫秒值来创建一个特定的Date对象。
调用Date对象的getTime()方法 ,它将返回Date对象表示的毫秒值。 使用System.currentTimeMillis() ,直接获取当前时间的毫秒值,而无需创建Date对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class Test1Date { public static void main (String[] args) { Date d = new Date (); System.out.println(d); long time = d.getTime(); System.out.println(time); time += 2 * 1000 ; Date d2 = new Date (time); System.out.println(d2); Date d3 = new Date (); d3.setTime(time); System.out.println(d3); } }
我们把Date对象转换为指定格式的日期字符串这个操作,叫做日期格式化 ,
反过来把指定格式的日期符串转换为Date对象的操作,叫做日期解析 。
接下来,我们先演示一下日期格式化,需要用到如下的几个方法
注意:创建SimpleDateFormat对象时,在构造方法的参数位置传递日期格式,而日期格式是由一些特定的字母拼接而来的。
1 2 3 4 5 6 7 8 9 10 11 12 字母 表示含义 yyyy 年 MM 月 dd 日 HH 时 mm 分 ss 秒 SSS 毫秒 "2022年12月12日" 的格式是 "yyyy年MM月dd日" "2022-12-12 12:12:12" 的格式是 "yyyy-MM-dd HH:mm:ss" 按照上面的格式可以任意拼接,但是字母不能写错
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 public class Test2SimpleDateFormat { public static void main (String[] args) throws ParseException { Date d = new Date (); System.out.println(d); long time = d.getTime(); System.out.println(time); SimpleDateFormat sdf = new SimpleDateFormat ("yyyy年MM月dd日 HH:mm:ss EEE a" ); String rs = sdf.format(d); String rs2 = sdf.format(time); System.out.println(rs); System.out.println(rs2); String dateStr = "2022-12-12 12:12:11" ; SimpleDateFormat sdf2 = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss" ); Date d2 = sdf2.parse(dateStr); System.out.println(d2); } }
日期格式化&解析案例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 public class Test3 { public static void main (String[] args) throws ParseException { SimpleDateFormat sdf = new SimpleDateFormat ("yyyy-M-d H:m:s" ); long start = sdf.parse("2026-3-1 0:0:0" ).getTime(); long end = sdf.parse("2026-3-1 0:10:0" ).getTime(); long jia = sdf.parse("2026-3-1 0:3:47" ).getTime(); long pi = sdf.parse("2026-3-1 0:10:3" ).getTime(); if (jia >= start && jia <= end){ System.out.println("小贾同学参与成功!" ); }else { System.out.println("小贾同学参与失败!" ); } if (pi >= start && pi <= end){ System.out.println("小皮同学参与成功!" ); }else { System.out.println("小皮同学参与失败!" ); } long now = sdf.parse("2026-3-24 14:49:0" ).getTime(); long birth = sdf.parse("2003-3-4 0:0:0" ).getTime(); long diffMillis = now - birth; long days = diffMillis / (24 * 60 * 60 * 1000 ); System.out.println("出生天数:" + days + "天" ); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 public class MySimpleDate { public static void main (String[] args) { SimpleDateFormat sdf = new SimpleDateFormat (); Date date = new Date (); String format = sdf.format(date); System.out.println(format); SimpleDateFormat sdf2 = new SimpleDateFormat ("yyyy年MM月dd日 HH:mm:ss E" ); String format1 = sdf2.format(date); System.out.println(format1); String s = "2026年03月24日 14:17:49 周五" ; Date parse = null ; try { parse = sdf2.parse(s); } catch (ParseException e) { e.printStackTrace(); System.out.println("字符串的格式与工具中的模式字母不对应,请检查格式!" ); } System.out.println(parse); } }
Calendar类 Calendar类表示日历 ,它提供了一些比Date类更好用的方法。
因为Calendar类提供了方法可以直接对日历中的年、月、日、时、分、秒等进行运算。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 public class Test4Calendar { public static void main (String[] args) { Calendar now = Calendar.getInstance(); System.out.println(now); int year = now.get(Calendar.YEAR); System.out.println(year); int days = now.get(Calendar.DAY_OF_YEAR); System.out.println(days); Date d = now.getTime(); System.out.println(d); long time = now.getTimeInMillis(); System.out.println(time); now.set(Calendar.MONTH, 9 ); now.set(Calendar.DAY_OF_YEAR, 125 ); System.out.println(now); now.add(Calendar.DAY_OF_YEAR, 100 ); now.add(Calendar.DAY_OF_YEAR, -10 ); now.add(Calendar.DAY_OF_MONTH, 6 ); now.add(Calendar.HOUR, 12 ); now.set(2026 , 11 , 22 ); System.out.println(now); } }
为什么JDK8要新增日期类 1 2 3 4 5 6 7 8 在JDK7的日期类中方法较少, 线程不安全, 对象可变, 精度只能到毫秒; 而JDK8针对以上问题做了补充和优化;
LocalDataTime
全部都是静态
比如表示年月日用LocalDate类、
表示时间秒用LocalTime类、
表示年月日时分秒用LocalDateTime类等;
LocalDate类的基本使用
LocalTime类的基本使用
LocalDateTime类的基本使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 public class Test3_LocalDateTime { public static void main (String[] args) { LocalDateTime ldt = LocalDateTime.now(); System.out.println(ldt); int year = ldt.getYear(); int month = ldt.getMonthValue(); int day = ldt.getDayOfMonth(); int dayOfYear = ldt.getDayOfYear(); int dayOfWeek = ldt.getDayOfWeek().getValue(); int hour = ldt.getHour(); int minute = ldt.getMinute(); int second = ldt.getSecond(); int nano = ldt.getNano(); LocalDateTime ldt2 = ldt.withYear(2029 ); LocalDateTime ldt3 = ldt.withMinute(59 ); LocalDateTime ldt4 = ldt.plusYears(2 ); LocalDateTime ldt5 = ldt.plusMinutes(3 ); LocalDateTime ldt6 = ldt.minusYears(2 ); LocalDateTime ldt7 = ldt.minusMinutes(3 ); LocalDateTime ldt8 = LocalDateTime.of(2029 , 12 , 12 , 12 , 12 , 12 , 1222 ); LocalDateTime ldt9 = LocalDateTime.of(2029 , 12 , 12 , 12 , 12 , 12 , 1222 ); System.out.println(ldt9.equals(ldt8)); System.out.println(ldt9.isAfter(ldt)); System.out.println(ldt9.isBefore(ldt)); LocalDate ld = ldt.toLocalDate(); LocalTime lt = ldt.toLocalTime(); LocalDateTime ldt10 = LocalDateTime.of(ld, lt); } }
时区 由于世界各个国家与地区的经度不同,各地区的时间也有所不同,因此会划分为不同的时区。每一个时区的时间也不太一样。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 public class Test4_ZoneId_ZonedDateTime { public static void main (String[] args) { ZoneId zoneId = ZoneId.systemDefault(); System.out.println(zoneId.getId()); System.out.println(zoneId); System.out.println(ZoneId.getAvailableZoneIds()); ZoneId zoneId1 = ZoneId.of("America/New_York" ); ZonedDateTime now = ZonedDateTime.now(zoneId1); System.out.println(now); ZonedDateTime now1 = ZonedDateTime.now(Clock.systemUTC()); System.out.println(now1); ZonedDateTime now2 = ZonedDateTime.now(); System.out.println(now2); } }
Instant类 通过获取Instant的对象 可以拿到此刻的时间,
该时间由两部分组成:从1970-01-01 00:00:00 开始走到此刻的总秒数+不够1秒的纳秒数。
该类提供的方法如下图所示,可以用来获取当前时间,也可以对时间进行加、减、获取等操作。
作用:可以用来记录代码的执行时间,或用于记录用户操作某个事件的时间点 。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class Test5_Instant { public static void main (String[] args) { Instant now = Instant.now(); long second = now.getEpochSecond(); System.out.println(second); int nano = now.getNano(); System.out.println(nano); System.out.println(now); Instant instant = now.plusNanos(111 ); Instant now1 = Instant.now(); Instant now2 = Instant.now(); LocalDateTime l = LocalDateTime.now(); } }
格式化器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 public class MyDTF { public static void main (String[] args) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss" ); LocalDateTime now = LocalDateTime.now(); String format = formatter.format(now); System.out.println(format); String s = "2026-03-24 15:53:04" ; System.out.println(now.format(formatter)); LocalDateTime parse1 = LocalDateTime.parse(s, formatter); System.out.println(parse1); } }
Period类 其中Period用来计算日期间隔(年、月、日) ,
Duration用来计算时间间隔(时、分、秒、纳秒)
可以用来计算两个日期之间相隔的年、相隔的月、相隔的日。
只能两个计算LocalDate对象之间的间隔
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class MyPeriod { public static void main (String[] args) { LocalDate t1 = LocalDate.of(2001 ,5 ,3 ); LocalDate t2 = LocalDate.now(); Period between = Period.between(t1, t2); int years = between.getYears(); int months = between.getMonths(); int days = between.getDays(); System.out.println("从" +t1+"到今天,一共经历了:" +years+"年零" +months+"月零" +days+"天" ); } }
Duration类 它是用来表示两个时间对象的时间间隔。
可以用于计算两个时间对象相差的天数、小时数、分数、秒数、纳秒数;
支持LocalTime、LocalDateTime、Instant等时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 public class MyDuration { public static void main (String[] args) { LocalDateTime t1 = LocalDateTime.of(2026 , 3 , 23 , 20 , 20 , 10 ); LocalDateTime t2 = LocalDateTime.now(); Duration between = Duration.between(t1, t2); long seconds = between.getSeconds(); System.out.println("从" +t1+"开始到现在,已经连续玩了:" +seconds+"秒的游戏了..." ); System.out.println("从" +t1+"开始到现在,已经连续玩了:" +seconds/3600 +"小时,零" +seconds%3600 /60 +"分,零" +seconds%60 +"秒的游戏了..." ); long hours = between.toHours(); long days = between.toDays(); System.out.println(hours); System.out.println(days); } }
Period有啥作用?
可以用于计算两个LocalDate对象相差的年数、月数、天数。
Duration有啥作用?
可以用于计算两个时间对象相差的天数、小时数、分数、秒数、纳秒数,支持 LocalTime.LocalDateTime.lnstant等时间。
对象的深克隆 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 public class Phone implements Cloneable { private String brand; private double price; private double [] memory; @Override public String toString () { return "Phone{" + "brand='" + brand + '\'' + ", price=" + price + ", memory=" + Arrays.toString(memory) + '}' ; } public String getBrand () { return brand; } public void setBrand (String brand) { this .brand = brand; } public double getPrice () { return price; } public void setPrice (double price) { this .price = price; } public double [] getMemory() { return memory; } public void setMemory (double [] memory) { this .memory = memory; } public Phone () { } public Phone (String brand, double price, double [] memory) { this .brand = brand; this .price = price; this .memory = memory; } @Override public Phone clone () throws CloneNotSupportedException { Phone clone = (Phone) super .clone(); double [] clone1 = memory.clone(); clone.setMemory(clone1); return clone; } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class TestPhone { public static void main (String[] args) throws CloneNotSupportedException { Phone phone = new Phone ("锤子" ,998 ,new double []{8 ,12 ,16 }); Phone p2 = phone.clone(); p2.setBrand("魅族" ); p2.setPrice(2323 ); p2.getMemory()[1 ]= 4 ; System.out.println(p2); System.out.println(phone); } }