Java 8 日期和时间解读

转载自 Java 8 日期和时间解读

        现在,一些应用程序仍然在使用java.util.Date和java.util.Calendar API和它们的类库,来使我们在生活中更加轻松的处理日期和时间,比如:JodaTime。然而,Java 8 引进的新的类库来处理日期和时间,这可以使我们更加精细的控制时间的表示,可以管理不可变的时间对象,同时,不需要使用其它的类库,更加流畅的API在大多数情况下对性能也有很大的提升。下面我们来了解一下Java 8 日期和时间的一些基础知识:

LocalDate/LocalTime/LocalDateTime

        让我们从与 java.util.Date最相关的新的API开始: LocalDate:表示日期,不表示时间。 LocalTime:表示时间,不表示日期。 LocalDateTime:上面两者的组合。 所有的这些日期和时间表示类型,都表示某个区域的日期或者时间。但是,就像java.util.Date中的零区域信息一样,只是表示当前区域的日期和时间。

    首先这些API支持一个简单的实例:

LocalDate date = LocalDate.of(2018,2,13); 
// Uses DateTimeformatter.ISOLOCALDATE for which the format is: yyyy-MM-dd 
LocalDate date = LocalDate.parse("2018-02-13");
LocalTime time = LocalTime.of(6,30);
// Uses DateTimeFormatter.ISO_LOCAL_TIME for which the format is: HH:mm[:ss[.SSSSSSSSS]]
// this means that both seconds and nanoseconds may optionally be present.
LocalTime time = LocalTime.parse("06:30");LocalDateTime dateTime = LocalDateTime.of(2018,2,13,6,30);
// Uses DateTimeFormatter.ISO_LOCAL_DATE_TIME for which the format is the
// combination of the ISO date and time format, joined by 'T': yyyy-MM-dd'T'HH:mm[:ss[.SSSSSSSSS]]
LocalDateTime dateTime = LocalDateTime.parse("2018-02-13T06:30");

    在它们之间转换时比较简单的:

 // LocalDate to LocalDateTime 
LocalDateTime dateTime = LocalDate.parse("2018-02-13").atTime(LocalTime.parse("06:30"));

 

// LocalTime to LocalDateTime
LocalDateTime dateTime = LocalTime.parse("06:30").atDate(LocalDate.parse("2018-02-13"));// LocalDateTime to LocalDate/LocalTime
LocalDate date = LocalDateTime.parse("2018-02-13T06:30").toLocalDate();
LocalTime time = LocalDateTime.parse("2018-02-13T06:30").toLocalTime();

        除此之外,使用“加”“减”法来进行我们的日期和时间操作,像其它公用功能一样,简单的难以置信: 

LocalDate date = LocalDate.parse("2018-02-13").plusDays(5); 
LocalDate date = LocalDate.parse("2018-02-13").plus(3, ChronoUnit.MONTHS);

LocalTime time = LocalTime.parse("06:30").minusMinutes(30);
LocalTime time = LocalTime.parse("06:30").minus(500, ChronoUnit.MILLIS);LocalDateTime dateTime = LocalDateTime.parse("2018-02-13T06:30").plus(Duration.ofHours(2));// using TemporalAdjusters, which implements a few useful cases:
LocalDate date = LocalDate.parse("2018-02-13").with(TemporalAdjusters.lastDayOfMonth());

        现在,我们该如何从java.util.Date转换到LocalDateTime呢?它们又有哪些不同?好吧,这很简单:我们可以把一个时间类型转换为一个实例类型,这是从1970年1月1日开始的,然后,我们可以在当前区域使用这个实例来实例化一个LocalDateTime。

LocalDateTime dateTime = LocalDateTime.ofInstant(new Date().toInstant(), ZoneId.systemDefault());

        为了转换日期,我们可以简单的使用java8时间类型的实例。需要注意的一点是,虽然LocalDate,LocalTime和LocalDateTime不包含任何区域和偏移信息,它们代表了一个特定区域的日期和/或时间,同样的,它们带有该区域的偏移。因此,为了正确的将特定类型转换为实例,我们需要提供一个偏移。

// represents Wed Feb 28 23:24:43 CET 2018
Date now = new Date();// represents 2018-02-28T23:24:43.106
LocalDateTime dateTime = LocalDateTime.ofInstant(now.toInstant(), ZoneId.systemDefault());// represent Wed Feb 28 23:24:43 CET 2018
Date date = Date.from(dateTime.toInstant(ZoneOffset.ofHours(1)));
Date date = Date.from(dateTime.toInstant(ZoneId.systemDefault().getRules().getOffset(dateTime)));

时间差异-持续时间和日期段

        就像你所注意到的一样,在上面的一个例子中,我们使用了一个Duration对象。Duration和Period是两个日期之间时间的两种表示方法,前者用秒和纳秒来区分时间,后者使用年月日。

        它们应该在哪些情况下使用呢?如果你需要知道两个LocalDate表示的时间之间日期段的时候,你可以选择使用Period:

Period period = Period.between(LocalDate.parse("2018-01-18"), LocalDate.parse("2018-02-14"));

        当你想要找出两个日期之差(即时间间隔)的时候,你可以选择使用Duration。

Duration duration = Duration.between(LocalDateTime.parse("2018-01-18T06:30"),LocalDateTime.parse("2018-02-14T22:58"));

        当我们使用toString()方法输出Period和Duration的时候,将会用到基于ISO-8601标准的一种特定格式。Period的模式是PnYnMnD,日期中n定义了当前的年月日。P1Y2D3意思就是1年2个月3天。模式中的‘P’表示日期标识符,它告诉我们接下来的格式表示的是日期。使用这种模式我们同样可以创建一个基于使用parse()方法的string的日期。

// represents a period of 27 days
Period period = Period.parse("P27D");

        使用Duration的时候,我们稍微偏离了ISO-8601标准,因为Java8不使用同样的模式。ISO-8601定义的模式是PnYnMnDTnHnMn.nS,它是建立在Period的模式基础上并对其进行了拓展的一种时间表示。在这个模式中,T是时间标识符,所以,它后面定义的是时分秒。

        Java8中,Duration使用了两种模式,当把一个String解析为一个Duration的时候使用PnDTnHnMn.nS模式,当在一个Duration实例中调用toString方法的时候,使用PTnHnMn.nS模式。

        最后同样重要的是,我们可以使用相应的方法类型来检索一个时期或者时间中的任何一部分。各种类型的日期时间通过使用ChronoUnit枚举类型也同样支持。让我们来看下面的例子:

// represents PT664H28M
Duration duration = Duration.between(LocalDateTime.parse("2018-01-18T06:30"),LocalDateTime.parse("2018-02-14T22:58"));// returns 664
long hours = duration.toHours();// returns 664
long hours = LocalDateTime.parse("2018-01-18T06:30").until(LocalDateTime.parse("2018-02-14T22:58"),ChronoUnit.HOURS);

时区时间和偏移时间

        到目前为止,我们已经展示了新日期时间API如何使事情变的更加简单。但是,真正不同的是在时区环境下更加简单的使用日期和时间。Java8为我们提供了ZonedDateTime和OffsetDateTime,前者是LocalDateTime针对特定区域(例如:法国/巴黎)的信息,后者LocalDateTime的偏移。两者有什么不同呢?OffsetDateTime使用UTC/格林威治和制定日期之间的固定时差,ZonedDateTime制定了表示时间的区域,并且考虑到了夏令时。

        转换为这些类型是很简单的:

OffsetDateTime offsetDateTime = LocalDateTime.parse("2018-02-14T06:30").atOffset(ZoneOffset.ofHours(2));
// Uses DateTimeFormatter.ISO_OFFSET_DATE_TIME for which the default format is
// ISO_LOCAL_DATE_TIME followed by the offset ("+HH:mm:ss").
OffsetDateTime offsetDateTime = OffsetDateTime.parse("2018-02-14T06:30+06:00");ZonedDateTime zonedDateTime = LocalDateTime.parse("2018-02-14T06:30").atZone(ZoneId.of("Europe/Paris"));
// Uses DateTimeFormatter.ISO_ZONED_DATE_TIME for which the default format is
// ISO_OFFSET_DATE_TIME followed by the the ZoneId in square brackets.
ZonedDateTime zonedDateTime = ZonedDateTime.parse("2018-02-14T06:30+08:00[Asia/Macau]");
// note that the offset does not matter in this case.
// The following example will also return an offset of +08:00
ZonedDateTime zonedDateTime = ZonedDateTime.parse("2018-02-14T06:30+06:00[Asia/Macau]");

        当在它们之间转换的时候,你必须要记住把ZoneDateTime转换为OffsetDateTime的时候,需要考虑到夏令时,反而言之,当把OffsetDateTime转换为ZonedDateTime的时候,意味着你将不会获得区域的信息,也不适用夏令时的规则。应为偏移没有定义任何时区规则,也不会绑定到任何区域。

ZonedDateTime winter = LocalDateTime.parse("2018-01-14T06:30").atZone(ZoneId.of("Europe/Paris"));
ZonedDateTime summer = LocalDateTime.parse("2018-08-14T06:30").atZone(ZoneId.of("Europe/Paris"));// offset will be +01:00
OffsetDateTime offsetDateTime = winter.toOffsetDateTime();
// offset will be +02:00
OffsetDateTime offsetDateTime = summer.toOffsetDateTime();OffsetDateTime offsetDateTime = zonedDateTime.toOffsetDateTime();OffsetDateTime offsetDateTime = LocalDateTime.parse("2018-02-14T06:30").atOffset(ZoneOffset.ofHours(5));
ZonedDateTime zonedDateTime = offsetDateTime.toZonedDateTime();

        现在,如果我们想要知道相对于我们所在时区特定区域的时间和偏移量,该怎么办?这里同样定义了一些方便的功能!

// timeInMacau represents 2018-02-14T13:30+08:00[Asia/Macau]
ZonedDateTime timeInMacau = LocalDateTime.parse( "2018-02-14T13:30" ).atZone( ZoneId.of( "Asia/Macau" ) );
// timeInParis represents 2018-02-14T06:30+01:00[Europe/Paris]
ZonedDateTime timeInParis = timeInMacau.withZoneSameInstant( ZoneId.of( "Europe/Paris" ) );OffsetDateTime offsetInMacau = LocalDateTime.parse( "2018-02-14T13:30" ).atOffset( ZoneOffset.ofHours( 8 ) );
OffsetDateTime offsetInParis = offsetInMacau.withOffsetSameInstant( ZoneOffset.ofHours( 1 ) );

        如果在任何时候,你都必须手动在两种类型之间转换的话,将会很麻烦。在这方面,Spring Framework给我们提供了帮助。Spring为我们提供了一些开箱即用的日期时间转换器,这些转换器注册在ConversionRegistry,在org.springframework.format.datetime.standard.DateTimeConverters类中可以找到。

    这使用这些转换器的时候,重要的是要知道在区域和偏移之间是不会转换的。比如说,ZonedDateTimeToLocalDateTimeConverter将会返回它所指定的区域的LocalDateTime,而不是你应用程序中所代表的。

ZonedDateTime zonedDateTime = LocalDateTime.parse("2018-01-14T06:30").atZone(ZoneId.of("Asia/Macau"));
// will represent 2018-01-14T06:30, regardless of the region your application has specified
LocalDateTime localDateTime = conversionService.convert(zonedDateTime, LocalDateTime.class);

    最后重要的是,你可以检索ZonId.getAvailableZoneIds()来查找所有可用的时区,或者使用ZoneId.SHORT_IDS,它包含了一些简写版本的时区,例如:EST,CST等等。

格式化—使用DateTimeFormatter

        当然,世界上不同的区域使用不同的格式来指定时间。一个应用程序可能使用MM-dd-yyyy,另一个可能会使用dd/MM/yyyy.一些应用程序想要解决这些不一致的格式,统一用yyyy-MM-dd来表示日期。使用java.util.Date的时候,我们很快的就会转向使用多个格式化器。但是DateTimeFormatter类,为我们提供了操作模式,使我们可以使用单一的格式化器来处理多种格式!让我们通过一些例子来看一下。

// Let’s say we want to convert all of patterns mentioned above.
// 09-23-2018, 23/09/2018 and 2018-09-23 should all convert to the same LocalDate.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("[yyyy-MM-dd][dd/MM/yyyy][MM-dd-yyyy]");
LocalDate.parse("09-23-2018", formatter);
LocalDate.parse("23/09/2018", formatter);
LocalDate.parse("2018-09-23", formatter);

        方括号中的内容定义了模式中的可操作部分,通过使我们的各种格式可选,匹配string的第一个模式将会被用来转换我们表示的日期。当我们使用混合模式的时候,阅读起来将会非常困难,所以,让我们使用builder模式来创建我们的DateTimeFormatter。

DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendOptional( DateTimeFormatter.ofPattern( "yyyy-MM-dd" ) ).optionalStart().appendPattern( "dd/MM/yyyy" ).optionalEnd().optionalStart().appendPattern( "MM-dd-yyyy" ).optionalEnd().toFormatter();

        这些是包含多种模式的基础知识,但是,如果我们的模式仅仅是略有不同该怎么办呢?让我们来看一下yyy-MM-dd和yyyy-MMM-dd。

// 2018-09-23 and 2018-Sep-23 should convert to the same LocalDate.
// Using the ofPattern example we’ve used above will work:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("[yyyy-MM-dd][yyyy-MMM-dd]" );
LocalDate.parse( "2018-09-23", formatter );
LocalDate.parse( "2018-Sep-23", formatter );// Using the ofPattern example where we reuse the common part of the pattern
DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "yyyy-[MM-dd][MMM-dd]" );
LocalDate.parse( "2018-09-23", formatter );
LocalDate.parse( "2018-Sep-23", formatter );

        但是,当转换为String的时候,不可以使用支持多种格式的格式化器,因为当我们使用格式化器把我们的日期转换为string表示的时候,它也将使用可选模式。

LocalDate date = LocalDate.parse("2018-09-23");
// will result in 2018-09-232018-Sep-23
date.format(DateTimeFormatter.ofPattern("[yyyy-MM-dd][yyyy-MMM-dd]" ));
// will result in 2018-09-23Sep-23
date.format(DateTimeFormatter.ofPattern( "yyyy-[MM-dd][MMM-dd]" ));

        21世纪以来,很明显的我们必须要考虑到全球化,所以我们想要为我们的用户提供本地化的日期。为了确保你的DateTimeFormatter返回一个指定的本地日期,你可以简单的做以下一些工作:

DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "EEEE, MMM dd, yyyy" ).withLocale(Locale.UK);DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern("yyyy-MMM-dd" ).toFormatter(Locale.UK);

        可以使用Locale.getAvailableLocales()方法来找出可用的区域设置。

     现在,你接受到日期模式可能比你使用的带有更多的信息。一旦提供的日期表示不符合模式,DateTimeFormatter就会抛出异常。让我们更进一步的来探讨这个问题及其处理方法。

// The issue: this will throw an exception.
LocalDate date = LocalDate.parse("2018-02-15T13:45");
// We provide a DateTimeFormatter that can parse the given date representation.
// The result will be a LocalDate holding 2018-02-15.
LocalDate date = LocalDate.parse("2018-02-15T13:45", DateTimeFormatter.ISO_LOCAL_DATE_TIME);

让我们来创建一个可以处理ISO日期、时间和日期时间模式的格式化器。

DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendOptional( DateTimeFormatter.ISO_LOCAL_DATE ).optionalStart().appendLiteral( "T" ).optionalEnd().appendOptional( DateTimeFormatter.ISO_LOCAL_TIME ).toFormatter();

        现在我们可以完美的执行以下内容:

// results in 2018-03-16
LocalDate date = LocalDate.parse( "2018-03-16T06:30", formatter );
LocalDate date = LocalDate.parse( "2018-03-16", formatter );
// results in 06:30
LocalTime time = LocalTime.parse( "2018-03-16T06:30", formatter );
LocalTime time = LocalTime.parse( "06:30", formatter );
LocalDateTime localDateTime = LocalDateTime.parse( "2018-03-16T06:30", formatter );

        下一个问题是什么呢?如果您试图解析LocalDateTime的日期模式,该怎么办?反之,如果您期望通过一个日期表示得到一个LocalTime,该怎么办?

// will throw an exception
LocalDateTime localDateTime = LocalDateTime.parse("2018-03-16", formatter);
LocalDate localDate = LocalDate.parse("06:30", formatter);

        最后的这两个问题,并没有单一的正确解决方法,但是它依据你需要什么,或者是这些日期和时间表示的是什么,或者可以表示什么?这种魔法般的方法可以在TemporalQuery的使用中找到,你也可以使用TemporalQuery为模式的一部分来创建缺省值。

        如果我们开始使用的是LocalDateTime,但是你只是想要一个LocalTime或者是一个LocalTime,你将会接受到LocalDateTime的对应部分。为了创建一个LocalDateTime,我们需要它所持有的日期和时间的默认值。日入说,如果你没有提供日期的信息,我们将会得到一个当前日期的返回值,如果你没有提供时间信息,我么会认为这是一天的起始。

        由于我们正在返回一个LocalDateTime,它不会被解析为一个LocalDate或者是LocalTime,所以,让我们使用ConversionService来得到 一个正确的格式。

TemporalQuery<TemporalAccessor> myCustomQuery = new MyCustomTemporalQuery();
// results in 2018-03-16
LocalDateTime localDateTime = conversionService.convert( formatter.parse( "2018-03-16", myCustomQuery ), LocalDateTime.class );
// results in 00:00
LocalTime localTime = conversionService.convert( formatter.parse( "2018-03-16", myCustomQuery ), LocalTime.class );class MyCustomTemporalQuery implements TemporalQuery<TemporalAccessor>
{@Overridepublic TemporalAccessor queryFrom( TemporalAccessor temporal ) {LocalDate date = temporal.isSupported( ChronoField.EPOCH_DAY )? LocalDate.ofEpochDay( temporal.getLong( ChronoField.EPOCH_DAY ) ) : LocalDate.now();LocalTime time = temporal.isSupported( ChronoField.NANO_OF_DAY )? LocalTime.ofNanoOfDay( temporal.getLong( ChronoField.NANO_OF_DAY ) ) : LocalTime.MIN;return LocalDateTime.of( date, time );}
}

使用TemporalQuery我们可以检查哪些信息是当前的,并且可以为许多丢失的信息提供缺省值,这使我们可以很简单的在我们的应用程序中使用合理的逻辑转换为我们所需要的类型。

结论

大多数新功能都需要时间来理解和习惯,Java8 Date/Time API也不例外。新的API为我们提供了访问所需要的更好的正确格式,为我们提供了使用日期时间操作的更加标准、更具可读性的方式。使用这些技巧和窍门,我们几乎可以涵盖我们所有的用例。


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/329805.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

云计算产值将超3000亿美元 亚马逊微软谷歌居三甲

腾讯科技讯 3月27日消息&#xff0c;据外电报道&#xff0c;云计算曾经主要是无法承担建造和维护基础设施的初创公司的解决方案&#xff0c;但对于管理数字业务的大型企业而言&#xff0c;云计算正快速成为省钱的管理数字业务的方式。市场调研公司IDC在上月的一份调查数据显示&…

oracle中join另一个表后会查询不出一些数据_面试必备 | 8个Hive数据仓工具面试题锦集!...

是新朋友吗&#xff1f;记得先点蓝字关注我哦&#xff5e;今日课程菜单Java全栈开发 | Web前端H5大数据开发 | 数据分析人工智能Python | 人工智能物联网进入数据时代&#xff0c;大数据技术成为互联网发展的核心要素之一。与此同时大数据开发工程师的薪资也成为行业内高薪的代…

springboot-Initializer例子及分析

【README】 1&#xff0c;本文主要编写了 初始化器例子并分析了其调用路径&#xff1b; 2&#xff0c;初始化器的执行顺序 先于 后置处理器&#xff1b; 后置处理器&#xff0c;refer2 springboot&#xff1a;BeanPostProcessor示例及分析_PacosonSWJTU的博客-CSDN博客【RE…

ASP.NET 开发人员不必担心 Node 的五大理由

哦别误会……我真的很喜欢 Node&#xff0c;而且我觉得它提出的概念和模式将在很长一段时间内&#xff0c;对服务端 Web 编程产生深远的影响。即使随着时间的推移 Node 过气了&#xff0c;我们肯定可以从下一个牛逼玩意身上或多或少的感觉到它的影响(不管好的和/或坏的)。而在这…

Spring Boot面试题

转载自 Spring Boot面试题 Spring Boot 是微服务中最好的 Java 框架. 我们建议你能够成为一名 Spring Boot 的专家。问题一 Spring Boot、Spring MVC 和 Spring 有什么区别&#xff1f; SpringFrameSpringFramework 最重要的特征是依赖注入。所有 SpringModules 不是依赖注入就…

synchronized原理_Java并发编程 -- synchronized保证线程安全的原理

线程安全是并发编程中的重要关注点&#xff0c;应该注意到的是&#xff0c;造成线程安全问题的主要诱因有两点&#xff0c;一是存在共享数据(也称临界资源)&#xff0c;二是存在多条线程共同操作共享数据。因此为了解决这个问题&#xff0c;我们可能需要这样一个方案&#xff0…

转:Java 7 种阻塞队列详解

转自&#xff1a; Java 7 种阻塞队列详解 - 云社区 - 腾讯云队列&#xff08;Queue&#xff09;是一种经常使用的集合。Queue 实际上是实现了一个先进先出&#xff08;FIFO&#xff1a;First In First Out&#xff09;的有序表。和 List、Set ...https://cloud.tencent.com/de…

微软Build 2016前瞻:让开发者编写能畅行所有设备的app

本周三&#xff0c;5000名软件开发者将齐聚旧金山莫斯康展览中心参加微软公司年度开发者大会&#xff08;Build 2016&#xff09;&#xff0c;和往年一样&#xff0c;微软在大会上发布了一系列新的技术支持。 据透露&#xff0c;微软将会让开发人员编写可以在任何Windows设备上…

XSS的那些事儿

转载自 XSS的那些事儿XSS是什么XSS&#xff0c;Cross-site scripting&#xff0c;跨站脚本攻击&#xff0c;为了区分与CSS&#xff0c;起名为XSS。黑客利用网站的漏洞&#xff0c;通过代码注入的方式将一些包含了恶意攻击脚本程序注入到网页中&#xff0c;企图在用户加载网页时…

js 时间戳转换成时间_JavaScript 时间戳转成日期格式

我们在开发中经常需要把时间戳转化成日期格式&#xff0c;但 JavaScript 本身自带的 Date 方法并不像 PHP date 的那么强大。因此&#xff0c;我们就需要自己动手写一个方法。首先我们要先了解下需要用到的 JavaScript 自带的 Date 对象的方法&#xff1a;getDate&#xff1a;获…

java阻塞队列小结

【README】 1&#xff0c;本文介绍了java的7个阻塞队列&#xff1b; 2&#xff0c;阻塞队列的作用 做缓冲作用&#xff0c;如缓冲kafka消息&#xff0c;而不是直接发送给kafka&#xff0c;减少kafka集群的压力&#xff1b;【1】阻塞队列 BlockingQueue 概述 1&#xff0c;队…

来自.NET FM的感谢信

掐指一算&#xff0c;我们的播客 .NET FM 已经上线一周了&#xff01;&#xff01;&#xff01;不过瞅下节节攀升的流量&#xff0c;二位主播一边感叹 .NET 中文社区的热情&#xff0c;一边摸了摸瘪下去的荷包&#xff1a; • 首日访问 > 2000人次 • 五日访问 > 5000人次…

并发场景下MySQL存在的问题及解决思路

转载自 并发场景下MySQL存在的问题及解决思路 目录1、背景2、表锁导致的慢查询的问题3、线上修改表结构有哪些风险&#xff1f;4、一个死锁问题的分析5、锁等待问题的分析6、小结 一、背景对于数据库系统来说在多用户并发条件下提高并发性的同时又要保证数据的一致性一直是数据…

python queue 生产者 消费者_【python】-- 队列(Queue)、生产者消费者模型

队列(Queue)在多个线程之间安全的交换数据信息&#xff0c;队列在多线程编程中特别有用队列的好处&#xff1a;提高双方的效率&#xff0c;你只需要把数据放到队列中&#xff0c;中间去干别的事情。完成了程序的解耦性&#xff0c;两者关系依赖性没有不大。一、队列的类型&…

关于.NET技术前途问题的讨论

我去年曾经在论坛发起过关于.NET技术前途问题这个话题的讨论&#xff0c;也引起了很多同行和朋友的回复&#xff0c;时间过去大半年&#xff0c;自己也有了一些新的理解。本文的目的就是将其中一些精彩的观点整理出来并谈谈自己的观点。 引子 我们都知道微软.NET技术更新速度快…

用枚举enum实现单例

【README】 1&#xff0c;effectivejava 讲到使用 枚举类实现单例的例子&#xff0c;非常好用&#xff1b;2&#xff0c;好处如下&#xff1a; 不用定义私有构造器&#xff1b;不用定义获取单例的方法&#xff0c;如 getInstance() &#xff1b;通过 枚举类.INSTANCE() 就可以…

前端面试常考系列一

转载自 前端面试常考系列一 一、简述HTML5的优点和缺点&#xff1f; 优点&#xff1a; 1、网络标准统一、HTML5是由W3C推出的。 2、多设备、跨平台 &#xff0c;移植性强。 3、自适应网页设计。 4、即时更新。 5、新增了几个标签&#xff0c;有助于开发人员定义重要的内容&…

基于轻量型Web服务器Raspkate的RESTful API的实现

在上一篇文章《Raspkate - 基于.NET的可运行于树莓派的轻量型Web服务器》中&#xff0c;我们已经了解了Raspkate这一轻量型Web服务器&#xff0c;今天&#xff0c;我们再一起了解下如何基于Raspkate实现简单的RESTful API。 模块 首先让我们了解一下“模块”的概念。Raspkate的…

python股票自动买卖视频教程_十分钟学会用Python交易股票

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼本文通过讲述 [单股票均线策略] 在 Ricequant 量化平台的实现&#xff0c;熟悉平台并快速入门、创建自己的量化策略代码 。难易度&#xff1a;入门级.从一下几点说起&#xff1b;1 确定框架&#xff1a;[单股票均线策略] 的主要策略…

前端面试常考系列二

转载自 前端面试常考系列二 一、外部引用CSS有几种方式&#xff0c;有何区别 外部引用CSS的方式有两种分别是link和import。 区别如下&#xff1a; 1、link是XHTML标签&#xff0c;除了加载CSS外&#xff0c;还可以定义RSS等其它事务&#xff1b;import属于CSS范畴&#xff0c;…