开发工具分享
  • 首页
  • 计算科学
  • 文化旅游
  • 项目和网站
    • OSSEZ 计算技术
    • USRealEstate 社区
    • 地区文化
    • CWIKI.US
    • BUG.OSSEZ.COM
    • RSS.OSSEZ.COM
CWIKIUS.CN
一个有独立思考和温度的清新站
Computer Science

Java 8 及其后续版本的新遍历 forEach

Java 的 List 遍历通常会使用迭代器(Iterator)来进行遍历 Iterator 与 Iterable Iterator 为 Java中的迭代器对象,是能够对 List 这样的集合进行迭代遍历的底层依赖。而 Iterable 接口里定义了返回 Iterator 的方法,相当于对 Iterator 的封装,同时实现了Iterable 接口的类可以支持 for each循环。     Java 遍历集合的演进 Java 最开始设计的时候都会使用迭代器来对集合进行遍历。 类似下面的写法是不是非常熟悉,在定义集合后,然后使用迭代器,然后使用迭代器中的 hasNext() 方法来完成遍历。 List<String> testList = Arrays.asList("A", "B", "C"); Iterator iterator = testList.iterator(); while (iterator.hasNext()) { logger.debug((String) iterator.next()); } 上面的代码运行后,我们会知道输出应该为:A,B,C 使用 for 循环 因为上面的方法有时候会出点问题,比如说空对象异常呀。 或者通常没有办法获得当前遍历的下标等等。 然后就有很多人会开始使用一个 for 循环。 List<String> testList = Arrays.asList("A", "B", "C"); logger.debug("--- FOR ---"); for (int i = 0; i < testList.size(); i++) { logger.debug("{} > {}", i, testList.get(i)); } 当你运行上面的代码后,控制台的输出应该为: 15:38:55.241 [main] DEBUG com.ossez.java8.Java8ForEachUnitTest - --- FOR --- 15:38:55.241 [main] DEBUG com.ossez.java8.Java8ForEachUnitTest - 0 > A 15:38:55.242 [main] DEBUG com.ossez.java8.Java8ForEachUnitTest - 1 > B 15:38:55.242 [main] DEBUG com.ossez.java8.Java8ForEachUnitTest - 2 > C 需要记住的是,Java 中 List 的下标是从 0 开始的。 然后就有点郁闷了,有时候我们会对 List 遍历个多次,然后每次都 i 的话,经常都不知道 i 到最后的 i 的值是多少了。 更有可能的是,一些可爱的代码会用到 i,j ,k,m,n 运气不好会看到好几个。 for 的另外一种写法 针对上面的情况,如果你只是需要遍历的话,你还是可以考虑这样写。 List<String> testList = Arrays.asList("A", "B", "C"); logger.debug("--- FOR LOOP ---"); for (String s : testList) { logger.debug(s); } 如果需要下标的话,还是可以在里面直接定义一个 i 进行一些操作的。 在 JDK 5 以后的版本中,这种写法越来越多了,通常直接定义 i 的循环就比较少了。 上面的这个代码的可读性就更强一些了。 forEach 这个在 JDK 8 以后就可以这样写了。 List<String> testList = Arrays.asList("A", "B", "C"); logger.debug("--- FOR EACH ---"); testList.forEach(s -> { logger.debug(s); }); 这个是使用的 lambda 表达式的的循环,有点装逼的写法。 基本上和上面 for 的第二种写法差不多,如果你的集合实现了 Iterable 接口的话,通常就可以这样写了。 如果你能读读 JDK 源代码的话,就知道 Iterable 对迭代器进行了封装。     forEach 比直接 for 要高端一点点。 总结 不管采用什么样的写法,第一种直接迭代的写法是比较少见的。 通常不使用迭代器直接写的原因是集合不好操作。 Java 的遍历方式也越来越方便了,具体希望怎么遍历还是通过具体问题具体分析。掌握 1 到 2 种遍历方式基本上也够用了。   https://www.ossez.com/t/java-8-foreach/13725

2021年09月08日 0Comments 739Browse 0Like Read more
Computer Science

使用 Jackson – 将字符串转换为 JsonNode 对象

概述 本快速指南的主要目的是如何使用 Jackson 2 来将一个字符串转换为 JsonNode 对象。 JsonNode 定义在 com.fasterxml.jackson.databind.JsonNode 包中。 快速转换 可以使用下面的代码直接进行转换。 转换的方式也比较简单,在定义好 ObjectMapper 对象后,直接使用这个对象的 readTree 方法将输入的字符串转换为 JsonNode 对象。 考察下面的代码: @Test public void whenParsingJsonStringIntoJsonNode_thenCorrect() throws JsonParseException, IOException { String jsonString = "{"k1":"v1","k2":"v2"}"; ObjectMapper mapper = new ObjectMapper(); JsonNode actualObj = mapper.readTree(jsonString); assertNotNull(actualObj); } 低级别的转换 在有些情况下,你可能需要使用更加低级别的转换,比如说在转换的时候需要对一些输出参数进行设置。 那么你就需要先配置 Parser 了。 与前面的快速转换不同的是,在你 new 了一个新的 ObjectMapper 对象后,你需要从这个对象中获得 Factory。 然后再创建一个 Parser,最后再调用 readTree 的方法。 请考察下面的代码: @Test public void givenUsingLowLevelApi_whenParsingJsonStringIntoJsonNode_thenCorrect() throws JsonParseException, IOException { String jsonString = "{"k1":"v1","k2":"v2"}"; ObjectMapper mapper = new ObjectMapper(); JsonFactory factory = mapper.getFactory(); JsonParser parser = factory.createParser(jsonString); JsonNode actualObj = mapper.readTree(parser); assertNotNull(actualObj); } JsonNode 的使用 当 JSON 字符串被处理成了 JsonNode 对象后,那我们可以使用 JSON Tree Model 来对转换后的 JSON 对象进行操作。 例如下面的代码,首先我们完成了字符串到 JSON 对象的转换,然后转换完成后,我们通过 K1 的对定义来获得值。 @Test public void givenTheJsonNode_whenRetrievingDataFromId_thenCorrect() throws JsonParseException, IOException { String jsonString = "{"k1":"v1","k2":"v2"}"; ObjectMapper mapper = new ObjectMapper(); JsonNode actualObj = mapper.readTree(jsonString); // When JsonNode jsonNode1 = actualObj.get("k1"); assertThat(jsonNode1.textValue(), equalTo("v1")); } 结论 在使用 fasterxml 的 jackson 包对 Json 数据操作之前,首先需要做的事情就是将输入的 String 或者文件或者不同的输入流转换为 JsonNode 对象。 后续的操作就是对 JsonNode 的对象进行操作了。     例如,上面我们的一个 JsonNode 对象是一个数组,那么我们可以对上面的数组中转换后的对象进行遍历。   https://www.ossez.com/t/jackson-jsonnode/13724

2021年09月08日 0Comments 813Browse 0Like Read more
Computer Science

如何修改 Discourse 的域名

 如果你参考了 GitHub 上的安装指南 页面中的内容安装了一个 Discourse 实例后希望对自己安装的实例修改域名的使用手册。 如果你使用的是 Discourse 官方主机服务 的话,请参考 针对 Discourse 的云服务配置你的域名 页面中的详细内容。 假设,你现在希望修改你的 Discourse 实例的 域名从 talk.foo.com → talk.bar.com。 让我们开始这个过程吧。 在 DNS 的高级设置中,设置 TTL 为 low(低) 你希望让所有人都知道你的域名被修改了,因此你可以在你的域名 DNS 中设置 TTL 时间为低,例如可以设置为 60 分钟。 这个设置的主要目的是能够让你的 DNS 修改更快的生效。互联网中 DNS 的修改是需要时间的,因为有缓存的存在。 从站点中删除所有有关老的域名配置 访问 /admin/site_settings 然后搜索所有有关老的域名的配置。 如果你的搜索中找到了一些有关老的域名的配置,请确定你将上面的配置进行修改。 在 app.yml 文件中编辑 Discourse 的配置  可选的,你可以再次运行 ./discourse-setup 命令,然后通过这个命令提示的输入信息将新的域名更新到 app.yml 配置文件中。 在 app.yml 文件中,编辑 hostname 的内容。 ## Discourse 实例中的主机名将会被修改为如下 DISCOURSE_HOSTNAME: 'talk.bar.com' (同时,如果你还使用了 CDN 的话,你可以在 app.yml 文件中,将有关 CDN 的配置进行注释掉。在完成修改后,再将注释取消就可以了。) 在完成上面的配置后,需要对 Discourse 进行重构: ./launcher rebuild app 当你完成上面的重构后,你的站点只能通过新的域名来访问了。 修改你的 DNS 配置 将老的域名的 DNS 记录删除 修改新域名的 DNS 记录,将记录指向到你的 Discourse 服务地址。 当完成上面的配置后,你应该是没有问题通过新修改的域名来访问你的 Discourse 站点的。 你也可以同时在站点进行重构的时候修改你的 DNS 配置信息。 校验所有功能都能够正常访问,在我们对功能进行校验的时候,我们希望先确定我们能够正常登录我们的 Discourse 系统。这个就是下面的主题需要解决的问题… 修改第三方登录  基于你如何进行登录的方式不同,你需要马上对这个进行修改,否则你在域名修改完成后就没有办法通过第三方进行登录了。 你的 Twitter, Facebook, Google, Yahoo, GitHub 社交媒体账号登录配置中同时也需要修改来让回调地址和你新修改的地址一致。 请参考官方的相关文章来进行配置和修改。 将主题中所有有关老站点的引用替换为新站点的域名 现在所有主题和帖子中有关站点主题的链接都还是老的域名的,我们现在需要修改这个,帖子中的链接指向新的域名。让我们来进行操作: BEFORE AFTER ./launcher enter app 然后输入并且输入下面的命令: discourse remap talk.foo.com talk.bar.com 根据提示的内容进行修改后,再执行下面的命令: rake posts:rebake 主题中的 remaps 现在将会使用新的域名地址替换为老的域名地址,然后我们重新生成了所有的主题,以避免有所遗漏。 至此,所有修改域名的配置都已经完成了! (如果开始你注释掉了 CDN 的配置信息的话,不要忘记将上面的修改改回来。) 想知道 在主题中的输入对话框是如何创建的吗? https://www.ossez.com/t/discourse/13717/2

2021年09月08日 0Comments 842Browse 0Like Read more
Computer Science

在 Discourse 中如何使用输入对话框

如下图显示的内容,可以在输入框中输入文本,然后在主题中可以根据你输入的文本重新生成字符串:     效果演示 请在下面的输入框中输入文本,然后观察输出的变化 ZNAME在邮件列表中使用的名字 ZCOUNTRYFRDEUSCNAUCA 你的邮件地址: =ZNAME=-US@example.com 需要的插件 如果需要在你的 Discourse 安装中使用这个功能,你需要使用 discourse-placeholder-theme-component 这个仓库。 单击下面的链接来访问这个仓库。  仓库链接 如何安装 访问你的管理员控制台界面。 然后选择主题的组件,单击 安装按钮。     在弹出的对话框中输入 Git 的仓库地址。 根据官方的仓库,我们 fork 了一个,GitHub - ossez-com/discourse-placeholder-theme-component: discourse-placeholder-theme-component 在这个仓库中在,主要是添加了简体中文的语言文件。 当安装成功后,你就可以看到下面的界面了。     需要注意的是,在配置的界面中,需要将主题选择上。 如果你不选择主题的话,那么你的这个插件就没有办法使用。     根据 Discourse 的设计逻辑,主题下面是组件,我们现在安装的是组件,在组件安装完成后需要和主题进行关联。 因此如果你不选择的话,或者选择部分的话,那么用户在切换主题的时候,可能这个组件就不能用了。   https://www.ossez.com/t/discourse/13720

2021年09月08日 0Comments 716Browse 0Like Read more
Computer Science

Confluence 数据中心版本接近生命周期了

也不知道 Confluence 的官方是怎么想的。 Confluence 的数据中心支持在 2024年2月2号停止技术支持,所有的服务都会使用云服务。 这个无异于是自杀类型的举动,很多公司的数据是非常敏感的是没有办法上云的,不知道他们是不是脑袋被驴踢了?     估计不少公司又要开始找下家了。   https://www.ossez.com/t/confluence/13716

2021年09月04日 0Comments 822Browse 0Like Read more
Computer Science

RedHat 8 时间同步和时区修改

在新的 RedHat 8 或者更新的 Linux 版本中,我们可以使用     timedatectl 来对时间进行相关的操作进行一些修改。 设置时区 当系统完成初始化以后,对时间的设置是非常必要的,可以使用下面的方法对时区进行修改。 例如,如果你希望修改时区为美国东部时间的话,直接运行下面的命令: timedatectl set-timezone America/New_York 就可以了。 设置 NTP 同步 以前,我们还需要装一大堆的 NTP 服务来对时间进行同步。 现在只需要运行: timedatectl set-ntp yes 就可以设置自动同步了。 是不是非常方便了。 总结 可以只运行 2 句话解决时间同步和时区的问题。 [root@monitor ~]# timedatectl set-timezone America/New_York [root@monitor ~]# timedatectl set-ntp yes 运行下下面的命令查看下状态吧。 [root@monitor ~]# timedatectl status Local time: Thu 2021-09-02 15:39:12 EDT Universal time: Thu 2021-09-02 19:39:12 UTC RTC time: Thu 2021-09-02 19:39:12 Time zone: America/New_York (EDT, -0400) NTP enabled: yes NTP synchronized: yes RTC in local TZ: no DST active: yes Last DST change: DST began at Sun 2021-03-14 01:59:59 EST Sun 2021-03-14 03:00:00 EDT Next DST change: DST ends (the clock jumps one hour backwards) at Sun 2021-11-07 01:59:59 EDT Sun 2021-11-07 01:00:00 EST [root@monitor ~]# 查看下当前的状态,是不是越来越方便了。 https://www.ossez.com/t/redhat-8/13714

2021年09月03日 0Comments 745Browse 0Like Read more
Computer Science

RedHat 8 如何检查端口是否联通

在 Linux 调试的时候非常麻烦的就是检查端口是否联通。 其中可能有各种原因导致端口没有联通,通常为操作系统本身的防火墙,托管服务器中心的防火墙等。 因为网络不通,导致各种问题的出现。 nc 也被称为 netcat 就是你的好朋友了。 安装 运行下面的命令就可以进行安装了,如果你的 dnf 不能使用,那么试下 yum dnf install nc Linux 的 nc 命令用于设置路由器。 执行本指令可设置路由器的相关参数。 执行命令检查端口 可以直接执行下面的命令,来检查特定地址的特定端口是否是开放的。 nc -z -v 127.0.0.1 10050 上面的命令查看 IP 地址为:127.0.0.1 端口为:10050 如果出现下面的返回,则表明端口是联通的。 [root@monitor ~]# nc -z -v 127.0.0.1 10050 Ncat: Version 7.50 ( https://nmap.org/ncat ) Ncat: Connected to 127.0.0.1:10050. Ncat: 0 bytes sent, 0 bytes received in 0.01 seconds. [root@monitor ~]# 如果你需要查看远程服务器的特定端口的话,修改不同的地址就行。 总结 需要注意的是,IP 地址和端口直接使用空格分开。 -z 使用 0 输入/输出模式,只在扫描通信端口时使用。 -v 显示指令执行过程。 如果你还需要了解其他参数,请参考相关手册。 https://www.ossez.com/t/redhat-8/13713  

2021年09月03日 0Comments 744Browse 0Like Read more
Computer Science

IntelliJ IDEA 中如何将 POM 中的版本号快速提出为属性

在 Java 的项目中的 POM 配置文件。 我们可能希望将一个依赖的版本号提升为属性。 如下图:     上面的依赖的版本号为属性。 解决办法 在 IntelliJ IDEA 中可以使用快捷键。 Ctrl+Alt+V 来完成这个操作。 将光标移动到版本号的数字上面,然后使用上面的快捷键。 这个时候将会弹出上面的对话框,如果你不希望进行修改的话,直接 OK 就可以了。 当然你也可以选择从菜单中进入,进入的路径为:Refactor | Extract | Property   https://www.ossez.com/t/intellij-idea-pom/13712

2021年09月03日 0Comments 750Browse 0Like Read more
Computer Science

IntelliJ IDEA 如何快速查看提交代码的对比

有时候,我们在提交代码的时候希望知道我们对文件进行了什么修改。 那么在 Commit 对话框中,选择需要提交的文件,双击鼠标左键盘就可以了。     这个时候你的 IntelliJ IDEA 将会为你打开一个对比的对话框。 在这个对比的对话框中将会把你的本地文件版本和 Git 的版本进行对比。 在这个对比中,你就可以看到你需要提交的文件的不同了。     这样做的好处是能够让你在提交之前对需要提交的内容进行一些对比,以便于确定你的代码是正确和你需要修改的。   https://www.ossez.com/t/intellij-idea/13710

2021年09月02日 0Comments 781Browse 0Like Read more
Computer Science

JDK 8 及其后续 JDK 中 Period 和 Duration

我们都知道 JDK 8 以后开始使用了新的 joda 日期处理 API。 在这个 API 中,新增了 Period 和 Duration 这 2 个类,用于计算 2 个日期之间的间隔。 下面对这 2 个类进行一些比较和说明,从使用上来说,如果你不需要秒或者纳秒一级的比较的话,就用 Period ,Period 的比较粒度更粗,通常只能精确到,天(Days),月(Months)和 年(Years)。 Duration 是按照纳秒级别的比较,通常会非常精确,不会丢精度,Period 有可能会丢精度。 线程安全和可变 这 2 个类都是: 线程安全(thread-safe) 不可变(immutable) 对比和区别 2 个类比较的精度不不同。 Period 包含年数,月数,天数,而 Duration 只包含秒,纳秒。 Period 只能返回年数,月数,天数;Duration可以返回天数,小时数,分钟数,毫秒数等。 2 个类可以使用的类型不同。 Period 只能使用 LocalDate,换句话说 Period 只能使用 Date 对象。 Duration 是可以使用 Instant 对象的。 例如下面的代码: Instant t1, t2; ... long ns = Duration.between(t1, t2).toNanos(); 将会计算 2 个时间之间的纳秒的不同。 考察下面计算生日的代码: Period p = Period.between(birthday, today); long p2 = ChronoUnit.DAYS.between(birthday, today); System.out.println("You are " + p.getYears() + " years, " + p.getMonths() + " months, and " + p.getDays() + " days old. (" + p2 + " days total)"); 代码将会输出为: You are 41 years, 8 months, and 0 days old. (15219 days total) 因为我们在生日和日期的计算的时候,并不需要非常高的精度,因此上面的代码是不是非常方便? 再也不用受到老的 Java 日期 API 的折磨了。   https://www.ossez.com/t/jdk-8-jdk-period-duration/13709

2021年09月01日 0Comments 845Browse 0Like Read more
1…124125126127128…304
Archives
  • June 2026
  • May 2026
  • April 2026
  • March 2026
  • February 2026
  • January 2026
  • December 2025
  • November 2025
  • October 2025
  • September 2025
  • August 2025
  • July 2025
  • June 2025
  • May 2025
  • April 2025
  • March 2025
  • February 2025
  • January 2025
  • December 2024
  • November 2024
  • October 2024
  • September 2024
  • August 2024
  • July 2024
  • June 2024
  • May 2024
  • April 2024
  • March 2024
  • February 2024
  • January 2024
  • December 2023
  • November 2023
  • October 2023
  • September 2023
  • August 2023
  • July 2023
  • June 2023
  • May 2023
  • April 2023
  • December 2022
  • November 2022
  • October 2022
  • September 2022
  • August 2022
  • May 2022
  • April 2022
  • March 2022
  • February 2022
  • January 2022
  • December 2021
  • November 2021
  • October 2021
  • September 2021
  • August 2021
  • July 2021
  • June 2021
  • May 2021
  • April 2021
  • March 2021
  • February 2021
  • January 2021
  • December 2020
  • November 2020
  • October 2020
  • September 2020
  • August 2020
  • July 2020
  • June 2020
  • May 2020
  • April 2020
  • March 2020
  • February 2020
  • January 2020
  • December 2019
  • November 2019
  • October 2019
  • September 2019
  • August 2019
  • July 2019
  • June 2019
  • May 2019
  • April 2019
  • March 2019
  • February 2019
  • January 2019
  • December 2018
  • November 2018
  • October 2018
  • September 2018
  • August 2018
  • July 2018
  • June 2018
  • May 2018
  • April 2018
  • March 2018
Categories
  • Computer Science (2,367)
    • Confluence (663)
    • Gradle (12)
  • U.S. (523)
  • 文化旅游 (146)

COPYRIGHT © 2020 CWIKIUS. ALL RIGHTS RESERVED.

THEME KRATOS MADE BY VTROIS

湘ICP备2020018253号-1