JDK 8的Calendar.Builder

勇敢的Java新世界的定义特征之一是Java空间中构建器模式的日益普及。 Groovy似乎是JVM上最流行的替代语言(对于Java),以在核心库以及Groovy支持的库和框架中大量使用Builder而闻名。 乔希布洛赫与覆盖带来的图案为Java开发者社区心态前列模式在项目#2他的极具影响力的第二版的有效的Java 。 JDK中已经添加了几个构建器,包括J2SE 1.7中添加了Locale.Builder 。 在本文中,我将简要介绍JDK 8附带的 Calendar.Builder 。

如今,Java开发人员通常通过以下任一方法填充Calendar类的实例:
调用其中一个接受实例的冗长内容列表的“ set”方法之一,或者通过在该实例上一个接另一个地调用各个“ set”方法。 接下来的两个代码清单中演示了这两种填充Calendar实例的典型方法。

使用单个“设置”方法填充日历

/*** Demonstrate pre-JDK 8 method of instantiating Calendar instance using* "set" method for main fields.*/
public static void demoCalendarWithSingleSet()
{final Calendar calendar =Calendar.getInstance(TimeZone.getTimeZone(timeZoneId),ENGLISH);calendar.set(2013, APRIL, 6, 15, 45, 22);out.println("Calendar via Constructor: " + stringifyCalendar(calendar));
}

使用多个单独的“设置”方法填充日历

/*** Demonstrate pre-JDK 8 method of instantiating Calendar instance using* individual "set" calls for each pair of field names and values.*/
public static void demoCalendarWithIndividualSets()
{final Calendar calendar =Calendar.getInstance(TimeZone.getTimeZone(timeZoneId),ENGLISH);calendar.set(YEAR, 2013);calendar.set(MONTH, APRIL);calendar.set(DATE, 6);calendar.set(HOUR, 3);calendar.set(MINUTE, 45);calendar.set(SECOND, 22);calendar.set(AM_PM, PM);out.println("Calendar via set methods: " + stringifyCalendar(calendar));
}

旁注:在以上两个示例中,我都使用了现代Java另一个日益流行的功能 : static import 。 诸如ENGLISH , YEAR和SECOND之类的常量实际上是从Locale和Calendar之类的类中静态导入的。 正如我之前所写 ,静态导入在Java开发人员中似乎越来越流行,特别是考虑到流畅接口的趋势。

上面显示的两种“传统”方法显示了填充Calendar实例的不同方法。 一种极端情况是分别设置每个单独的字段,而另一种极端情况是使用单个“设置”方法设置所有重要字段。 每种方法都有其优势。 与多集方法相比,单个“集”方法具有“未完成”对象的状态更少,但是多集方法更具可读性,因为基于每个“集”的第一个参数,被设置值的名称是明确的“ 方法。 单集方法有点笨拙,因为它需要六个整数,可以很容易地将它们按顺序混合起来,因为除了隐式阶数之外,没有明显的方法可以区分哪个整数是哪个整数。

Calendar.Builder利用Bloch所描述的Builder的广告收益:消除了“在[对象]构造过程中出现不一致状态的情况”。 下一个代码清单对此进行了演示。

Calendar.Builder允许具有可读设置的单语句实例化

/*** Demonstrate using JDK 8's Calendar.Builder to instantiate an instance of* Calendar using the set methods to set each field individually based on* field name and value.*/public static void demoCalendarWithCalendarBuilderSetFields(){final Calendar calendar =new Calendar.Builder().set(YEAR, 2013).set(MONTH, APRIL).set(DATE, 6).set(HOUR, 15).set(MINUTE, 45).set(SECOND, 22).setTimeZone(TimeZone.getTimeZone(timeZoneId)).setLocale(ENGLISH).build();out.println("Calendar via Calendar.Builder 'set' Fields: "+ stringifyCalendar(calendar));}

在上面的代码清单中,创建了Calendar实例并将其填充到一条语句中,从而消除了使对象在多个语句中处于不一致状态的风险。 此示例保留了传统的单个“集合”方法方法[ set(int,int) ]的可读性,并具有在实例化时立即完全填充对象的附加安全性。

对于希望提供较少的单个“设置”方法的开发人员, Calendar.Builder另一个机会是使用setDate(int,int,int)和setTimeOfDay(int,int,int)方法,如下面的代码清单所示。

Calendar.Builder将日期和时间设置为两个呼叫

/*** Demonstrate using JDK 8's Calendar.Builder to instantiate an instance of* Calendar using the "setDate" and "setTimeOfDay" builder methods.*/
public static void demoCalendarWithCalendarBuilderSetDaySetTime()
{final Calendar calendar =new Calendar.Builder().setDate(2013, APRIL, 6).setTimeOfDay(15, 45, 22).setTimeZone(TimeZone.getTimeZone(timeZoneId)).setLocale(ENGLISH).build();out.println("Calendar via Calendar.Builder setDate/setTimeOfDay: "+ stringifyCalendar(calendar));
}

用这种方法键入的字符和行数较少,但是它部分地重新引入了一个缺点,即由于两个方法中的每一个都使用三个整数,因此无意间切换了整数参数的可能性(或者setTimeOfDay()的重载版本将占用一个整数setTimeOfDay()代表毫秒的第四个整数)。

对于希望在实例化过程中指定Calendar参数时具有最大灵活性的开发人员, Calendar.Builder提供了setFields(int…)方法,该方法采用任意长度的整数对,其中整数对的第一个整数表示要设置的字段,第二个整数表示要设置的字段表示该字段值的一对整数。 下一个代码清单中使用了此方法。

通过Calendar.Builder的setFields方法指定日历字段

/*** Demonstrate using JDK 8's Calendar.Builder to instantiate an instance of* Calendar using the setFields method that allows providing of Calendar* fields as key/value pairs.*/public static void demoCalendarWithCalendarBuilderSetPairs(){final Calendar calendar =new Calendar.Builder().setFields(YEAR, 2013, MONTH, APRIL, DATE, 6, HOUR, 15, MINUTE, 45, SECOND, 22).setTimeZone(TimeZone.getTimeZone("timeZoneId")).setLocale(ENGLISH).build();out.println("Calendar via Calendar.Builder setPairs: "+ stringifyCalendar(calendar));}

setFields(int ...)方法带来更大的风险,可能会破坏用于实例化Calendar新实例的整数的顺序,但是使用静态导入的Calendar常数确实可以提高可读性,并减少不正确混合整数的可能性。 如果提供了奇数个整数(意味着存在不完整的对),则抛出IllegalArgumentException 。

尽管Calendar.Builder在实例化和填充Calendar实例方面提供了一些便利,但是幸运地采用JDK 8的任何人都可以访问新的日期/时间API ,因此可能会问“为什么使用Calendar.Builder?”。 也许最好的答案是,有成千上万行使用和期望使用Calendar实例的现有代码,库和框架,因此可能需要很长时间才能完全消除对Calendar的需求(如果有的话)。 幸运的是, Calandar.Builder使得可以通过CalendarBulder.setInstant(long)轻松将Instant ( 新Java数据/时间API的一部分)实例转换成Calendar 。 下一个代码清单对此进行了演示。

使用Calendar.Builder将Instant转换为Calendar

/*** Demonstrate using JDK 8's Calendar.Builder to instantiate an instance of* Calendar based on "now" Instant.*/public static void demoCalendarWithCalendarBuilderInstant(){final Calendar calendar =new Calendar.Builder().setInstant(Instant.now().toEpochMilli()).setTimeZone(TimeZone.getTimeZone(timeZoneId)).setLocale(ENGLISH).build();out.println("Calendar via Calendar.Builder and Instant: " + stringifyCalendar(calendar));}

请注意, setInstant方法的重载版本接受Date来实例化Calendar 。 在这两种情况下,无论是使用setInstant(long)还是setInstant(Date)实例化,都不应调用Calender.Builder上的其他“ set”方法来避免IllegalStateException 。

使用Calendar.toInstant()可以很容易地朝另一个方向(从Calendar获取Instant ) 。 JDK 1.8的Calendar引入的其他方法与提供当前实例的日历类型 (作为字符串)或可用日历类型的集合(字符串的集合)有关。 当我在系统上运行Calendar.getAvailableCalendarTypes()时,看到以下三个字符串:“ gregory ”,“ Japanese ”和“ buddhist ”(与“ Supported Calendars”中记录的三个日历相同)

结论

与许多Java开发人员一样 ,我期待标准Java开发套件中内置的改进的Java数据/时间API。 但是,我也意识到,尤其是在大型代码库中,以及在使用期望使用CalendarDate库和框架时,我将在一段时间内无法摆脱CalendarDate的困扰。 JDK 8中Calendar.Builder的引入减轻了这一负担。

参考:来自JCG合作伙伴 Dustin Marx的JDK 8的Calendar.Builder,来自Inspired by Actual Events博客。

翻译自: https://www.javacodegeeks.com/2013/05/jdk-8s-calendar-builder.html

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

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

相关文章

oracle锁表会话超时时间,ORACLE快速彻底Kill掉的会话,防止锁表

ORACLE快速彻底Kill掉的会话,防止锁表2020-05-30编程之家收集整理的这篇文章主要介绍了ORACLE快速彻底Kill掉的会话,防止锁表,编程之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。万能是sql重启服务,不然,以下…

格式化文本

1.后台获取文本后文本内部存在回车,但是浏览器不能编译\n\t所以使用pre,使文本能够编译文本,2.若文本长度超出预设宽度,可以添加样式,下列代码,可以使超出后的文本自动换行。/*将文本解析为段落,是段落自动化行*/pre {…

webstorm快捷键

Ctrl/ 或 CtrlShift/ 注释(// 或者/*…*/ ) ShiftF6 重构-重命名 CtrlX 删除行 CtrlD 复制行 CtrlG 查找行 CtrlShiftUp/Down 代码向上/下移动。 F2 或ShiftF2 高亮错误或警告快速定位 写代码,按Tab 生成代码 选中文本&#…

vue支付密码

从网上搜索了好多都很麻烦&#xff0c;花了点事件自己做了个&#xff0c;简单轻便&#xff0c;老少皆宜 <template> <section class"pay-mask" click"close_mask" v-show"payshow"> <div class"container"> <div…

打造智能建筑商

构建API时&#xff0c;您应该始终考虑谁将使用它。 当API简单易用时&#xff0c;用户就会感到满意。 当用户满意时&#xff0c;每个人也都会满意。 但是出色的可用性并非总是容易实现的。 有一些模式对此有所帮助&#xff0c;在这篇文章中&#xff0c;我将重点介绍经典的构建器…

结合BeautyEye开源UI框架实现的较美观的Java桌面程序

BeautyJavaSwingRobot 结合BeautyEye开源UI框架实现的较美观的Java桌面程序&#xff0c;主要功能就是图灵机器人和一个2345网站万年历的抓取。。。。   挺简单而且实用的一个项目&#xff0c;实现出来的效果也还不错。希望可以学到知识的小可爱不对应该是帅哥&#xff0c;可…

oracle外表日期,三步教会您掌握oracle外表(external table)

三步教会你掌握oracle外表(external table)外表(externaltable)就像普通的表对像一样&#xff0c;可以select等&#xff0c;只是它是只读的&#xff0c;数据库中只保存了表结构的描述&#xff0c;表数据却没有存放在数据库内&#xff0c;而是存放在了文件系统上。当用户想偶尔使…

【从入门到放弃】23种设计模式(1):设计模式综述

一、设计模式的分类 总体来说设计模式分为三大类&#xff1a; 创建型模式&#xff0c;共五种&#xff1a;工厂方法模式&#xff08;Factory Method&#xff09;、抽象工厂模式&#xff08;Abstract Factory&#xff09;、单例模式&#xff08;Singleton&#xff09;、建造者模式…

Bootstrap警告框

前面的话 在网站中&#xff0c;网页总是需要和用户一起做沟通与交流。特别是当用户操作上下文为用户提供一些有效的警示框&#xff0c;比如说告诉用户操作成功、操作错误、提示或者警告等。在Bootstrap框架有一个独立的组件&#xff0c;实现类似的效果&#xff0c;这个组件被称…

python doctest测试

title: Python doctest测试 tags: Python --- doctest测试 python 提供了REPL&#xff08;read-eval-print loop&#xff0c;读取、求值、输出的循环&#xff09; 官方地址&#xff1a;https://docs.python.org/3/library/doctest.html """ This is the "e…

异步CDI事件

几天前&#xff0c;在我们的常规代码审查中&#xff0c;我的一位同事提出了一个问题&#xff0c;即如果可能&#xff0c;一次同时调用CDI观察者&#xff08;这样的方法带有参数Observes的方法&#xff09;会发生什么&#xff1f;用于不同的事件实例。 换句话说&#xff0c;在产…

oracle改了包怎么保存,Oracle存储过程、包、方法使用总结(推荐)

/***author&#xff1a;zhengwei*date:2017-04-28*desc:存储过程用法总结*/CREATE OR REPLACE PROCEDURE MYPROCEDURE(P_ID IN VARCHAR,P_STATUS OUT VARCHAR) --P_ID为输入参数 ,P_STATUS为输出参数AS---变量声明T_STATUS VARCHAR2(20);T_ID NUMBER;V_POSTYPE VARCHAR2(20);V_…

【2017级面向对象程序设计】第2次成绩排行

作业地址 https://edu.cnblogs.com/campus/fzu/OOP/homework/1864 评分标准 1&#xff09; C 流程图 or 文字描述程序结构 5分C 类图 or 文字描述程序结构 5分2&#xff09; 代码 共 10 分构造函数 &#xff1a;2 分析构函数 &#xff1a;2 分成员函数 显示当前所处楼层&#x…

css定位position

闲言碎语不多说&#xff0c;直接开写&#xff01; 关于定位 我们可以使用css的position属性来设置元素定位类型&#xff0c;position的设置项如下&#xff1a; a、relative生成相对定位元素&#xff0c;元素所占据的文档流的位置不变&#xff08;即元素不会脱离文档流&#x…

Spring Security登录

1.简介 本文将重点介绍使用Spring Security登录 。 我们将在前面的简单Spring MVC示例的基础上构建&#xff0c;因为这是设置Web应用程序和登录机制的必要部分。 2. Maven依赖 要将Maven依赖项添加到项目中&#xff0c;请参阅Spring Security with Maven文章 。 标准的spring-…

php运城,运城php培训

作用域&#xff1a;全局的request恳求   描绘&#xff1a;经过在Global中完成Application_Error办法&#xff0c;来到达侦听未经处置的异常   详细代码如下&#xff1a;sudo dtrace -qFn pid$target:Finding?Ray:Finding?Ray:r{ printf("%s\n", probefunc); } …

sql语句使用、说明及技巧

一、基础 1、说明&#xff1a;创建数据库CREATE DATABASE database-name 2、说明&#xff1a;删除数据库drop database dbname3、说明&#xff1a;备份sql server--- 创建 备份数据的 deviceUSE masterEXEC sp_addumpdevice disk, testBack, c:\mssql7backup\MyNwind_1.dat--- …

利用爬虫模拟网页微信wechat

1.登录页面&#xff0c;显示二维码 当我们打开网页微信时&#xff0c;会看到一个用于扫码登录的二维码&#xff0c;所以我们要模拟该页面给我们的页面也弄一个二维码 通过查看网页代码我们发现&#xff0c;这个二维码的标签为 这个src属性的最后一段每次访问都是不同的&#xf…

Bootstrap分页

前面的话 分页导航几乎在每个网站都可见&#xff0c;好的分页能给用户带来好的用户体验。本文将详细介绍Bootstrap分页 概述 在Bootstrap框架中提供了两种分页导航&#xff1a; ☑ 带页码的分页导航 ☑ 带翻页的分页导航 页码分页 带页码的分页导航&#xff0c;可能是最常见…

php 查询and or,php – SQL查询多个AND和OR不起作用

我有一个包含由双管分隔的值的单元格.我试图用以下内容搜索这个单元格的内容,(其中10是要搜索的数字)&#xff1f;,10&#xff05;,&#xff1f;&#xff05;和10我的查询似乎只返回10.没有其他变化.有人可以告诉我为什么它不起作用&#xff1f;提前谢谢了. (您在下面看到的SQL…