2020-ARTS-打卡第三天
文章目录
Algorithm
题目描述
反转一个单链表。
Example
输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
题目解答
迭代解法
|
|
第一次搞链表的题,还真是给难住了。此题的核心就是当前节点的指针要指向前一个节点,处理过程中还要考虑节点的丢失问题,所以要有一个变量保存当前节点的前一个节点,还要有一个变量来保存当前节点的下一个节点,方便后续的指针前移。此解法的时间复杂度为O(n),因其不需要额外的空间,所以空间复杂度为O(1)。
递归解法
|
|
此解的核心在于当有一部分是反转时,后续的反转问题,对于node.next.next = node这句,使用A->B两个节点进行示例,A.next为B,A.next.next为B.next,A.next.next = A为B.next = A,这样就实现了A与B两个节点的反转。这个递归看着还是有点懵,多看看就好了。
Review
Deeply Nested Code 本文是Idea作者代码味道系列的第二篇。主要讲述了开发中多种嵌套的坏味道,这种坏味道在开发中很常见。作者用实例来对坏味道进行了处理。
坏味道的代码
|
|
这个代码里面有两个for和一个if嵌套,这个代码主要逻辑就是在persistenceFields中查找与storedName的MappedField。
使用JAVA8来重写
作者使用JAVA8中的stream和flatMap来进行重构,但是最后只能返回一个带Optional的String,并不能返回那个MappedField。如果是在lambda中再进行for与if的处理看起来会更难受。
更好的进行封装
作者把代码中的第二个for与if抽取出来,形成一个方法,叫做hasName,这个方法就是用来告诉调用者mf中有没有与传入的名相同的名字。这时的代码变成了:
|
|
下一步就是把hasName方法移动MappedField(这里面使用F6就可以进行方法的移动,太神奇了)类中。这样封装后调用者就不必关心MappedField是怎么存储名字的了,封装的优点体现出来了。
额外的处理步骤
在进行了上面的处理后,就可以使用JAVA8的表达式来进行处理了,Stream,filter,findFirst一起。最终也可以返回一个带MappedField的Optional,漂亮。
总结
在Java8以前java中会出现很多for嵌套的语句,对于一些常见的底层集合操作来说可以理解,但是对于这种Domain类来说多层嵌套是不好的,可以对其进行封装,对于一些不需要调用方了解的东西可以在内部进行封装。考虑好类的职责,让代码编写更舒服。
Tip
在学习Linux命令中,对于一个不熟悉的命令,我们可以使用man命令来获取帮助,还可以使用tldr来获取命令的常用操作说明。对于原生的man命令,在命令查看不是很友好,可以使用以下三种办法来进行优化:
-
使用oh-my-zsh插件colored-man-pages来使man命令支持颜色显示
-
mac中把man命令输出到Preview应用中来查看,比如我要查看rsync命令是怎么使用
1
man -t rsync | open -f -a Preview.app
-
Emacs大法,在emacs中调用man命令就可以随心所欲的查找学习了
Share
今天分享的是Fix NoSuchMethodErrors这篇文章,在开发中总是会遇到NoSuchMethodError(看名字这是一个error,查了一个类继承关系,最终确实是继承自Error)这种情况,文章给出了处理和排查这种问题的方法,药到病除。