java8中的日期和时间API
一、背景
jdk 1.8
之前, Java
时间使用java.util.Date
和 java.util.Calendar
类。
Date today = new Date();
System.out.println(today); // 转为字符串
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String todayStr = sdf.format(today);
System.out.println(todayStr);
Date
的几个问题
1.如果不格式化,Date打印出的日期可读性差;
2.可以使用 SimpleDateFormat 对时间进行格式化,但 SimpleDateFormat 是线程不安全的(阿里巴巴开发手册中禁用static修饰SimpleDateFormat);
3,Date对时间处理比较麻烦,比如想获取某年、某月、某星期,以及 n 天以后的时间,如果用Date来处理的话真是太难了,并且 Date 类的 getYear()、getMonth() 这些方法都被弃用了
public class DataFormatUtils {
private static DateFormat dateFormat=new SimpleDateFormat("yyyy-mm-dd hh:MM:ss");
public static String format(Date date){
return dateFormat.format(date);
}
public static Date parse(String date){
Date newDate=null;
try {
newDate= dateFormat.parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
return newDate;
}
@Test
public void testSimpleDateFormat(){
ThreadPoolExecutor executor=new ThreadPoolExecutor(5, 10, 10L, TimeUnit.SECONDS, new BlockingArrayQueue<>(10),new MyThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
while (true){
executor.execute(new Runnable() {
@Override
public void run() {
try {
String dateString = dateFormat.format(new Date());
String dateString1=dateFormat.format(dateFormat.parse(dateString));
System.out.println("thread running:" + Thread.currentThread().getName()+" :"+dateString.equals(dateString1));
} catch (ParseException e) {
e.printStackTrace();
}
}
});
}
}
}
class MyThreadFactory implements ThreadFactory{
private AtomicInteger counter=new AtomicInteger();
@Override
public Thread newThread(Runnable r) {
Thread thread= new Thread(r);
int c = counter.getAndIncrement();
thread.setName("MyThreadPool:"+c);
return thread;
}
}
上述代码执行结果:
thread running:MyThreadPool:0 :false
Exception in thread "MyThreadPool:1" Exception in thread "MyThreadPool:7" Exception in thread "MyThreadPool:3" Exception in thread "MyThreadPool:8" Exception in thread "MyThreadPool:4" Exception in thread "MyThreadPool:6" java.lang.NumberFormatException: For input string: ""
thread running:MyThreadPool:0 :true
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Long.parseLong(Long.java:601)
at java.lang.Long.parseLong(Long.java:631)
at java.text.DigitList.getLong(DigitList.java:195)
at java.text.DecimalFormat.parse(DecimalFormat.java:2051)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:2162)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
at java.text.DateFormat.parse(DateFormat.java:364)
thread running:MyThreadPool:0 :false
at com.bjmashibing.system.baierhu.stream.DateFormat.DataFormatUtils$1.run(DataFormatUtils.java:36)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
thread running:MyThreadPool:14 :false
thread running:MyThreadPool:9 :true
thread running:MyThreadPool:17 :true
thread running:MyThreadPool:0 :true
Exception in thread "MyThreadPool:15" java.lang.NumberFormatException: empty String
at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
thread running:MyThreadPool:14 :true
结果在多线程情况下证明同一时间格式化之后返回结果不一致,查看format方法,可以看到
calendar.setTime(date);
多个线程使用同一个calendar,set时间,肯定会发生线程问题
解决方案:
1.在多线程中每次new 一个simpleDateFormat,注意对象的引用在多线程内,不能放在成员变量,否则还是会有多线程问题
2.使用threadLocal,threadLocal会保存每个线程中保存对象的副本,不会有多线程问题
public class DataFormatUtils { //private static DateFormat dateFormat;
private static final ThreadLocal<DateFormat>dateFormat=new ThreadLocal<DateFormat>(){
@Override /**创建的时候初始化值*/
protected DateFormat initialValue() {
return new SimpleDateFormat();
}
}; public static String format(Date date){
return dateFormat.get().format(date);
}
public static Date parse(String date){
Date newDate=null;
try {
newDate= dateFormat.get().parse(date);
} catch (ParseException e) {
e.printStackTrace();
}
return newDate;
}
@Test
public void testSimpleDateFormat(){
ThreadPoolExecutor executor=new ThreadPoolExecutor(5, 10, 10L, TimeUnit.SECONDS, new BlockingArrayQueue<>(10),new MyThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
while (true){
executor.execute(new Runnable() {
@Override
public void run() {
try {
//SimpleDateFormat dateFormat=new SimpleDateFormat("yyyy-mm-dd hh:MM:ss");
String dateString = DataFormatUtils.format(new Date());
System.out.println("dateString = " + dateString+"=="+Thread.currentThread().getName());
Date date=DataFormatUtils.parse(dateString);
System.out.println("date = " + date);
String dateString1=DataFormatUtils.format(date);
System.out.println("thread running:" + Thread.currentThread().getName()+" :"+dateString.equals(dateString1));
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
}
class MyThreadFactory implements ThreadFactory{
private AtomicInteger counter=new AtomicInteger();
@Override
public Thread newThread(Runnable r) {
Thread thread= new Thread(r);
int c = counter.getAndIncrement();
thread.setName("MyThreadPool:"+c);
return thread;
}
}
执行结果:
pr 11 17:22:00 CST 2021
thread running:MyThreadPool:9 :true
date = Sun Apr 11 17:22:00 CST 2021
thread running:MyThreadPool:5 :true
dateString = 21-4-11 下午5:22==MyThreadPool:2
dateString = 21-4-11 下午5:22==MyThreadPool:1
dateString = 21-4-11 下午5:22==MyThreadPool:6
date = Sun Apr 11 17:22:00 CST 2021
thread running:main :true
dateString = 21-4-11 下午5:22==main --- main线程出现的原因是选择的线程池拒绝策略为当队列中的任务线程池处理不过来时使用提交任务的线程去处理该任务
date = Sun Apr 11 17:22:00 CST 2021
thread running:MyThreadPool:7 :true
dateString = 21-4-11 下午5:22==MyThreadPool:3
使用jdk1.8的新api
public class DataFormatUtils { private static DateTimeFormatter dateFormat=DateTimeFormatter.ofPattern("yyyy-mm-dd HH:MM:ss");
public static String format(LocalDateTime date){
return dateFormat.format(date);
}
public static LocalDateTime parse(String date){
LocalDateTime newDate=LocalDateTime.parse(date,dateFormat);
return newDate;
}
@Test
public void testSimpleDateFormat(){
ThreadPoolExecutor executor=new ThreadPoolExecutor(5, 10, 10L, TimeUnit.SECONDS, new BlockingArrayQueue<>(10),new MyThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
while (true){
executor.execute(new Runnable() {
@Override
public void run() {
try {
String dateString = DataFormatUtils.format(LocalDateTime.now());
System.out.println("dateString = " + dateString+"=="+Thread.currentThread().getName());
LocalDateTime date=DataFormatUtils.parse(dateString);
System.out.println("date = " + date);
String dateString1=DataFormatUtils.format(date);
System.out.println("thread running:" + Thread.currentThread().getName()+" :"+dateString.equals(dateString1));
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
}
输出结果正常:
dateString = 2021-14-11 20:04:35==MyThreadPool:2
date = 2021-04-11T20:14:35
thread running:MyThreadPool:2 :true
dateString = 2021-14-11 20:04:35==MyThreadPool:2
date = 2021-04-11T20:14:35
thread running:MyThreadPool:2 :true
date = 2021-04-11T20:14:35
thread running:MyThreadPool:9 :true
thread running:MyThreadPool:4 :true
dateString = 2021-14-11 20:04:35==MyThreadPool:6
date = 2021-04-11T20:14:35
thread running:MyThreadPool:6 :true
dateString = 2021-14-11 20:04:35==MyThreadPool:3
date = 2021-04-11T20:14:35
thread running:MyThreadPool:3 :true
二、JDK 1.8
新的日期时间类型
Java8
引入的新的一系列API
,对时间日期的处理提供了更好的支持,清楚的定义了时间日期的一些概念,比如说,瞬时时间(Instant
),持续时间(duration
),日期(date
),时间(time
),时区(time-zone
)以及时间段(Period
)。
LocalDate
:不包含时间的日期,比如2019-10-14
。可以用来存储生日,周年纪念日,入职日期等。LocalTime
:与LocalDate
想对照,它是不包含日期的时间。LocalDateTime
:包含了日期及时间,没有偏移信息(时区)。ZonedDateTime
:包含时区的完整的日期时间,偏移量是以UTC
/格林威治时间为基准的。Instant
:时间戳,与System.currentTimeMillis()
类似。Duration
:表示一个时间段。Period
:用来表示以年月日来衡量一个时间段。DateTimeFormatter
:新的日期解析格式化类。
2.1 LocalDate
LocalDate
类内只包含日期,不包含具体时间。只需要表示日期而不包含时间,就可以使用它。
@Test
public void dateTest(){
LocalDate maxDate= LocalDate.MAX;
LocalDate minDate= LocalDate.MIN;
System.out.println("maxDate = " + maxDate);
System.out.println("minDate = " + minDate);
/**
* 输出:
* maxDate = +999999999-12-31
* minDate = -999999999-01-01
* */ LocalDate dateOf= LocalDate.of(2019,12,31);
System.out.println("dateOf = " + dateOf);
/**
* 输出:dateOf = 2019-12-31
* */ // LocalDate dateOfErr=LocalDate.of(20100, Month.JULY,33);
// System.out.println("dateOfErr = " + dateOfErr);
/**输出
* java.time.DateTimeException: Invalid value for DayOfMonth (valid values 1 - 28/31): 33
* */
LocalDate now= LocalDate.now();
System.out.println(now);
/**输出:2021-04-11*/
LocalDate zonshanghai= LocalDate.now(Clock.system(ZoneId.of(ZoneId.SHORT_IDS.get("CTT"))));
LocalDate zon= LocalDate.now(Clock.system(ZoneId.of(ZoneId.SHORT_IDS.get("SST"))));
System.out.println("zonshanghai = " + zonshanghai);
System.out.println("zon = " + zon);
/**输出:zonshanghai = 2021-04-11*/
/**输出:zon = 2021-04-11*/ int thisYear = zonshanghai.getYear();
int thisYearAnother = zonshanghai.get(ChronoField.YEAR);
System.out.println("今年是" + thisYear + "年");
System.out.println("今年是" + thisYearAnother + "年");
/**输出:
* 今年是2021年
* 今年是2021年
* */ }
2.2 LocalTime
LocalTime
只会获取时间,不获取日期。LocalTime
和LocalDate
类似,区别在于LocalDate不包含具体时间,而LocalTime
不包含具体日期。
@Test
public void localTime(){
LocalTime localTime= LocalTime.now();
System.out.println("localTime = " + localTime);
/**输出:localTime = 19:00:26.023*/
//获取小时的两种方式
int hour = localTime.getHour();
int thisHour = localTime.get(ChronoField.HOUR_OF_DAY);
System.out.println("当前时:" + hour);
System.out.println("当前时:" + thisHour);
/**输出:当前时:19
当前时:19*/
LocalTime anotherTime = LocalTime.of(20, 8, 8);
System.out.println("构造指定时间:" + anotherTime);
/**输出:构造指定时间:20:08:08*/
}
2.3 LocalDateTime
LocalDateTime
表示日期和时间组合。可以通过of()方法直接创建,也可以调用LocalDate
的atTime()
方法或LocalTime
的atDate()
方法将LocalDate
或LocalTime
合并成一个LocalDateTime
。
@Test
public void LocalDateTime(){
// 当前日期和时间
LocalDateTime today = LocalDateTime.now();
System.out.println("现在是:" + today);
/**现在是:2021-04-11T19:06:25.950*/ // 创建指定日期和时间
LocalDateTime anotherDay = LocalDateTime.of(2008, Month.AUGUST, 8, 8, 8, 8);
System.out.println("创建的指定时间是:" + anotherDay);
/**创建的指定时间是:2008-08-08T08:08:08*/
// 拼接日期和时间
// 使用当前日期,指定时间生成的 LocalDateTime
LocalDateTime thisTime = LocalTime.now().atDate(LocalDate.of(2008, 8, 8));
System.out.println("拼接的日期是:" + thisTime);
/**拼接的日期是:2008-08-08T19:06:25.951*/
// 使用当前日期,指定时间生成的 LocalDateTime
LocalDateTime thisDay = LocalDate.now().atTime(LocalTime.of(12, 24, 12));
System.out.println("拼接的日期是:" + thisDay);
/**拼接的日期是:2021-04-11T12:24:12*/
// 指定日期和时间生成 LocalDateTime
LocalDateTime thisDayAndTime = LocalDateTime.of(LocalDate.of(2008, 8, 8), LocalTime.of(12, 24, 12));
System.out.println("拼接的日期是:" + thisDayAndTime);
/**拼接的日期是:2008-08-08T12:24:12*/ // 获取LocalDate
LocalDate todayDate = today.toLocalDate();
System.out.println("今天日期是:" + todayDate);
/**今天日期是:2021-04-11*/
// 获取LocalTime
LocalTime todayTime = today.toLocalTime();
System.out.println("现在时间是:" + todayTime);
/**现在时间是:19:06:25.950*/
long lo=today.getSecond();
System.out.println(lo);
/**当前时间处于的秒*/
}
2.4 Instant
Instant
用于一个获取时间戳,与System.currentTimeMillis()
类似,但Instant
可以精确到纳秒。
@Test
public void instant(){
// 创建Instant对象
Instant instant = Instant.now();
// 通过ofEpochSecond方法创建(第一个参数表示秒,第二个参数表示纳秒)
Instant another = Instant.ofEpochSecond(365 * 24 * 60, 100); // 获取到秒数
long currentSecond = instant.getEpochSecond();
System.out.println("获取到秒数:" + currentSecond);
/**输出:获取到秒数:1618139520 为1970-01-01T00:00:00到现在的时间*/
// 获取到毫秒数
long currentMilli = instant.toEpochMilli();
System.out.println("获取到毫秒数:" + currentMilli);
/**输出:获取到毫秒数:1618139520871*/
}
2.5 Duration
Duration
的内部实现与Instant
类似,但Duration
表示时间段,通过between
方法创建,还可以通过of()
方法创建。
@Test
public void duridTest(){
LocalDateTime from = LocalDateTime.now();
LocalDateTime to = LocalDateTime.now().plusSeconds(10);
// 通过between()方法创建
Duration duration = Duration.between(from, to);
System.out.println("duration = " + duration.getSeconds());
/**输出10,可以使用该方法判断时间差*/
// 通过of()方法创建,该方法参数为时间段长度和时间单位。
// 7天
Duration duration1 = Duration.of(7, ChronoUnit.DAYS);
// 60秒
Duration duration2 = Duration.of(60, ChronoUnit.SECONDS);
}
可以用来判断时间差
2.6 Period
Period
与Duration
类似,获取一个时间段,只不过单位为年月日,也可以通过of
方法和between
方法创建,between
方法接收的参数为LocalDate
private static void period() {
// 通过of方法
Period period = Period.of(2012, 12, 24);
// 通过between方法
Period period1 = Period.between(LocalDate.now(), LocalDate.of(2020,12,31));
}
三、时间操作
3.1 时间比较
isBefore()
和isAfter()
判断给定的时间或日期是在另一个时间/日期之前还是之后。
以LocalDate
为例,LocalDateTime
/LocalTime
同理
public static void compare() {
LocalDate thisDay = LocalDate.of(2008, 8, 8);
LocalDate otherDay = LocalDate.of(2018, 8, 8); // 晚于
boolean isAfter = thisDay.isAfter(otherDay);
System.out.println(isAfter); // 早于
boolean isBefore = thisDay.isBefore(otherDay);
System.out.println(isBefore);
}
3.2 增加/减少年数、月数、天数
public static void plusAndMinus() {
// 增加
LocalDateTime today = LocalDateTime.now();
LocalDateTime nextYearDay = today.plusYears(1);
System.out.println("下一年的今天是:" + nextYearDay);
LocalDateTime nextMonthDay = today.plus(1, ChronoUnit.MONTHS);
System.out.println("下一个月的今天是:" + nextMonthDay); //减少
LocalDateTime lastMonthDay = today.minusMonths(1);
LocalDateTime lastYearDay = today.minus(1, ChronoUnit.YEARS);
System.out.println("一个月前是:" + lastMonthDay);
System.out.println("一年前是:" + lastYearDay);
}
3.3 时间修改
public static void edit() {
LocalDateTime today = LocalDateTime.now();
// 修改年为2012年
LocalDateTime thisYearDay = today.withYear(2012);
System.out.println("修改年后的时间为:" + thisYearDay);
// 修改为12月
LocalDateTime thisMonthDay = today.with(ChronoField.MONTH_OF_YEAR, 12);
System.out.println("修改月后的时间为:" + thisMonthDay);
}
3.4 时间计算
@Test
public void compute() {
// TemporalAdjusters 的静态方法
LocalDate today = LocalDate.now();
// 获取今年的第一天
LocalDate date = today.with(firstInMonth(DayOfWeek.MONDAY));
System.out.println("这一月的星期一:" + date); // Duration 计算
LocalDateTime from = LocalDateTime.now();
LocalDateTime to = LocalDateTime.now().plusMonths(1);
Duration duration = Duration.between(from, to); // 区间统计换算
// 总天数
long days = duration.toDays();
System.out.println("相隔" + days + "天");
// 小时数
long hours = duration.toHours();
System.out.println("相隔" + hours + "小时");
// 分钟数
long minutes = duration.toMinutes();
System.out.println("相隔" + minutes + "分钟");
}
TemporalAdjusters
的更多方法
四、时间日期格式化
DateTimeFormatter
默认提供了多种格式化方式,如果默认提供的不能满足要求,可以通过DateTimeFormatter
的ofPattern
方法创建自定义格式化方式。
@Test
public void format() {
LocalDateTime today = LocalDateTime.now();
// 两种默认格式化时间方式
String todayStr1 = today.format(DateTimeFormatter.BASIC_ISO_DATE);
String todayStr2 = today.format(DateTimeFormatter.ISO_LOCAL_DATE);
System.out.println("格式化时间:" + todayStr1);
/**输出:格式化时间:20210411*/
System.out.println("格式化时间:" + todayStr2);
/**输出:格式化时间:2021-04-11*/ String todayStr4 = today.format(DateTimeFormatter.ISO_LOCAL_TIME);
System.out.println(todayStr4);
/**输出:19:49:06.619*/ //自定义格式化
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("dd/MM/yyyy hh:MM:ss");
String todayStr3 = today.format(dateTimeFormatter);
System.out.println("自定义格式化时间:" + todayStr3);
/**输出:自定义格式化时间:11/04/2021 07:04:47*/
}
4.2 解析时间
4.1 中以何种方式格式化,这里需以同样方式解析。
@Test
public void parse() {
LocalDate date1 = LocalDate.parse("20080808", DateTimeFormatter.BASIC_ISO_DATE);
LocalDate date2 = LocalDate.parse("2008-08-08", DateTimeFormatter.ISO_LOCAL_DATE);
DateTimeFormatter dateTimeFormatter=DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss", Locale.CHINA);
LocalDateTime dateTime= LocalDateTime.parse("2020-08-03 22:11:23",dateTimeFormatter);
System.out.println(date1);
System.out.println(date2);
System.out.println(dateTime);
/**输出结果:
* 2008-08-08
* 2008-08-08
* 2020-08-03T22:11:23 这里的T是toString()方法中的,其本身是没有的
* */
}
五、总结
相较于Date
的优势
Instant
的精确度更高,可以精确到纳秒级;Duration
可以便捷得到时间段内的天数、小时数等;LocalDateTime
能够快速地获取年、月、日、下一月等;TemporalAdjusters
类中包含许多常用的静态方法,避免自己编写工具类;- 与
Date
的格式化方式SimpleDateFormat
相比,DateTimeFormatter
是线程安全的。
本文大部分转自:https://www.cnblogs.com/vandusty/p/12269050.html
java8中的日期和时间API的更多相关文章
- Day029 JDK8中新日期和时间API (二)
# JDK8中新日期和时间API (二) Instant介绍 Instant:时间线上的一个瞬时点. 这可能被用来记录应用程序中的事件时间 戳. 在处理时间和日期的时候,我们通常会想到年,月,日,时, ...
- Day029 JDK8中新日期和时间API (四)
JDK8中新日期和时间API 其他的一些API ZoneId:该类中包含了所有的时区信息,一个时区的ID,如 Europe/Paris ZonedDateTime:一个在ISO-8601日历系统时区的 ...
- Java8新特性--日期和时间API
如何正确处理时间 现实生活的世界里,时间是不断向前的,如果向前追溯时间的起点,可能是宇宙出生时,又或是是宇宙出现之前, 但肯定是我们目前无法找到的,我们不知道现在距离时间原点的精确距离.所以我们要表示 ...
- Java8 新的日期和时间API(笔记)
LocalDate LocalTime Instant duration以及Period 使用LocalDate和LocalTime //2017-03-20 LocalDate date = Loc ...
- 【Java8新特性】关于Java8中的日期时间API,你需要掌握这些!!
写在前面 Java8之前的日期和时间API,存在一些问题,比如:线程安全的问题,跨年的问题等等.这些问题都在Hava8中的日期和时间API中得到了解决,而且Java8中的日期和时间API更加强大.立志 ...
- 详解Java8的日期和时间API
详解Java8的日期和时间API 在JDK1.0的时候,Java引入了java.util.Date来处理日期和时间:在JDK1.1的时候又引入了功能更强大的java.util.Calendar,但是C ...
- 计算机程序的思维逻辑 (95) - Java 8的日期和时间API
本节继续探讨Java 8的新特性,主要是介绍Java 8对日期和时间API的增强,关于日期和时间,我们在之前已经介绍过两节了,32节介绍了Java 1.8以前的日期和时间API,主要的类是Date和 ...
- Java编程的逻辑 (95) - Java 8的日期和时间API
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...
- Java8系列 (六) 新的日期和时间API
概述 在Java8之前, 我们一般都是使用 SimpleDateFormat 来解析和格式化日期时间, 但它是线程不安全的. @Test public void test() { SimpleDate ...
随机推荐
- Android - Handler原理
Handler的主要作用是收发消息和切线程 功能一:收发消息 简单流程介绍 希望你看完这篇文章后也可以把流程自己讲出来,并且每个环节还可以讲出很多细节 他的消息机制离不开Looper.MessageQ ...
- XUPT-D
/* 泰泰学长又来玩数字了,泰泰学长想让你帮他求1-n的和,但是这次的求和可不是简单的1+2+...+n. 这次的求和是这样的,如果加到一个数字是2的指数倍,那就不加,反而减掉这个数. ...
- python基础学习之元组和字典的功能方法
什么是元组?(tuple) emmmmmm,这个没必要深究吧,就是一排'元素',一行 格式: a = (1,2,3,4,5,6,7,8,9)用小括号表示的,极为元组. 其有序,且不可更改,可以对比st ...
- Android的Proxy/Delegate Application框架
转自:http://blogs.360.cn/360mobile/2013/11/25/proxydelegate-application/#comment-77 有的时候,为了实现一些特殊需求,如界 ...
- 1.mysql读写
一.数据库读取(mysql) 参数 接受 作用 默认 sql or table_name string 读取的表名,或sql语句 无 con 数据库连接 数据库连接信息 无 index_col Int ...
- P1028_数的计算(JAVA语言)
题目描述 我们要求找出具有下列性质数的个数(包含输入的自然数n): 先输入一个自然数n(0n≤1000),然后对此自然数按照如下方法进行处理: 不作任何处理; 在它的左边加上一个自然数,但该自然数不能 ...
- TCP/IP协议的经典面试知识点总结
前言 大家好啊,我是汤小圆. 今天给大家推荐的是,TCP/IP协议的经典面试知识点总结,希望对大家有帮助,谢谢. 简介 我们平时经常听到的TCP/IP协议,其实是一个协议族: 只不过因为TCP.IP是 ...
- Swagger接口如何生成Html离线文档
A very simple tool that converts Swagger Api Document to Html File. 小记Swagger接口生成Html离线文档 由来 很多人用swa ...
- Android学习之Layoutinflater的用法
•她的第一次 话说,那是一个风雪交加的夜晚,看着她独自一个人走在漆黑的小道上,我抓紧跟了过去: 那晚,我们...... 记得第一次接触这个 Layoutinflater 应该是在学习 ListView ...
- Chrome89针对sessionStorage的更新导致数据共享问题
最近将chrome更新到最新的版本,然后发现以前可以正常使用的功能无法使用了,经过分析后发现是浏览器新版本才出现的问题,今天记录以下. 一.遇到的问题 我们具体的问题场景,在A页面中需要打开B页面,同 ...