外包公司不给交社保怎么办,榆林百度seo,ftp备份wordpress,哪些外国购物网站可以做I 前言 本次分享一下我所知道的如何写最少的代码的小技巧#xff0c;如果你有更好的方案#xff0c;欢迎在评论区留言#xff0c;方案很棒的话#xff0c;加我交流圈#xff0c;为你送上冬天的一杯奶茶~ Java#xff1a;我想返回多个返回值 秀一下Go的多返回值#xf… I 前言 本次分享一下我所知道的如何写最少的代码的小技巧如果你有更好的方案欢迎在评论区留言方案很棒的话加我交流圈为你送上冬天的一杯奶茶~ Java我想返回多个返回值 秀一下Go的多返回值
package main
import fmt// 返回 X Y 和 X * Y
func Computer(X, Y int) (int, int) {return X Y, X * Y
}众所周知Java仅支持单一返回值一般情况下如果需要返回多个对象我们会根据代码语义选择容器或者新建一个新的类把我们需要的数据包起来。 这样做有没有问题当然没有问题但是瑕疵就在于可能会产生没啥语义但又不得不存在的中间类我个人非常讨论该类代码那么该如何解决这种问题呢 首先需要认识到解决方案必须满足几个要求
代码可复用语义要清晰安全
既然如此我们可以采用泛型来满足复用、语义清晰的要求用中间类来满足代码安全性的要求代码如下
public class MultipleTwoReturnA, B {/** 第一个返回值 **/private final A first;/** 第二个返回值 **/private final B second;public MultipleTwoReturn(A first, B second) {this.first first;this.second second;}// 省略Get方法
}同时我们可以依赖于继承让该工具类拓展更多的参数
public class MultipleThreeReturnA, B, C extends MultipleTwoReturnA, B {/** 第三个返回值 **/private final C third;public MultipleThreeReturn(A first, B second, C third) {super(first, second);this.third third;}
}测试类
public class MultipleApp {public static void main(String[] args) {MultipleTwoReturnInteger, String returnTest MultipleApp.getReturnTest();System.out.println(returnTest.getFirst());System.out.println(returnTest.getSecond());}private static MultipleTwoReturnInteger, String getReturnTest() {MultipleTwoReturnInteger, String demo new MultipleTwoReturn(0, Kerwin Demo.);return demo;//加入Java开发交流君样756584822一起吹水聊天}
}本质还是普通对象但是加上泛型后威力剧增由于在方法定义时就强制了泛型约束语义非常清晰同时可以完全杜绝上述的无语义中间类当然一些必要的有业务含义的组装类不建议使用这种方式。
泛型我想new一个对象 想利用作为泛型约束却需要new一个T但是Java它new不出来啊 之前写过一个通用的Java爬虫接口里面有一个功能就是传入目标网页的即可获取到针对不同网页设计的Bean大概如下所示
public interface SpiderBeansHandleT {/** 获取Url **/String getUrl();/** 获取Cookie **/String getCookie();/** 获取CSS selector **/String getSelector();// ....}中间关键的一点即如何获取到这个Bean那个时候我只有一个想法new 一个 T
事实证明我过于天真了
但是换种思路既然new不出来那我就返回一下吧于是代码出炉了~
public interface SpiderBeansHandleT {/*** 获取Url*/String getUrl();/*** 获取Cookie*/String getCookie();/**** 获取CSS selector*/String getSelector();/**** 解析Element* param element element*/T parseElement(Element element);/**** Get Beans* param handle Bean对象 | handle对象* param T Bean类型* return ListBeans*/static T ListT getBeans(SpiderBeansHandleT handle) {ListT list new ArrayList();ListElement elements SpiderUtils.getElementWithCookie(handle.getUrl(), handle.getSelector(), handle.getCookie());for (Element element : elements) {T bean handle.parseElement(element);if (bean ! null) {list.add(bean);}//加入Java开发交流君样756584822一起吹水聊天}return list;}
}关键一步就在于
/**** 解析Element* param element element*/
T parseElement(Element element);那么这个小技巧有什么用呢仔细看会不会觉得它像一种设计模式的变形体没错真相只有一个模板方法模式 我需要一个处理爬虫的通用接口因为简单爬虫无非就是拿到url然后请求解析细节封装到自身的Bean里然后获取一个列表那么在开发业务代码的时候类似肯定有某些场景和需求具有高度的一致性那么使用这种设计方案即可大大的减少重复代码~ 方法你到底想干嘛 咱们在写代码的时候有没有遇到过这种问题写了一个工具类方法但是功能又过于单一虽说单一原则好吧但是一个小逻辑写一堆方法总感觉不得劲如何解决咧 Java8提供的函数式编程即可帮我们一定程度上解决这种问题如
// 写一个获取文件列表且判断是否为txt结尾的工具类方法新手会这么写
public static File getFileWithTxt(String path) throws IOException {File file new File(path);if (!file.exists()) {throw new IOException(File is not exist.);}if (file.getName().endsWith(.txt)) {return file;}return null;
}//加入Java开发交流君样756584822一起吹水聊天老手一般会把 .txt 作为参数传入但是某一天我需要判断文件大小文件长度甚至是文件内容的时候我该咋办再写N个
最好的方案即传入 Predicate 谓词让调用者自定义处理逻辑然后再把最常用的逻辑基于该方法复写一下拓展性Max代码如下
/**** 文件夹谓词匹配* param file 文件* param predicate 谓词匹配* return ListFile* throws IOException IOException*/
public static ListFile listFilesInDirWithFilter(File file, PredicateString predicate) throws IOException {if (!file.exists()) {throw new IOException(File is not exist.);}ListFile fileList new ArrayList();if (file.isDirectory()) {File[] files file.listFiles();for (File f : Objects.requireNonNull(files)) {fileList.addAll(listFilesInDirWithFilter(f, predicate));}} else {if (predicate.test(file.getName())) {fileList.add(file);}}return fileList;
}类似的还比如说处理 IO直接上代码
public static void readLine(BufferedReader br, ConsumerString handle, boolean close) {String s;try {while (((s br.readLine()) ! null)) {handle.accept(s);}} catch (IOException e) {e.printStackTrace();} finally {if (close br ! null) {try {br.close();} catch (IOException e) {e.printStackTrace();}}}
}//加入Java开发交流君样756584822一起吹水聊天方法说你到底想干嘛算了你想干嘛就干嘛吧请随意~
重载写的更多也是为了写的更少 写的更多也是为了写的更少这句话乍一听感觉非常矛盾但是编程经验比较丰富的小伙伴应该能体会到方法重载的威力尤其是在写工具类或者底层接口的时候建议大家先写一个大而全的内部方法然后一点点去根据需要重载它会有意想不到的好处。 最简单的例子如下
// Root 方法//加入Java开发交流君样756584822一起吹水聊天
private static void readLine(BufferedReader br, ConsumerString handle, boolean close) {String s;try {while (((s br.readLine()) ! null)) {handle.accept(s);}} catch (IOException e) {e.printStackTrace();} finally {if (close br ! null) {try {br.close();} catch (IOException e) {e.printStackTrace();}}}
}
// 重载方法一
public static void readLine(String path, ConsumerString handle, boolean close) {try {BufferedReader br new BufferedReader(new FileReader(path));readLine(br, handle, close);} catch (FileNotFoundException e) {e.printStackTrace();}
}// 重载方法二
public static void readLine(String path, ConsumerString handle) {readLine(path, handle, true);
}//加入Java开发交流君样756584822一起吹水聊天重载可以让我们的方法调用方式变得丰富多彩在语义明确的情况下写代码有如神助配合函数式编程可以让工具类或者底层接口的能力大大增强。 同时当我们需要调整某一个方法逻辑时也可以使用继续重载的方式将影响面降到最小尽量不动其他模块的代码。
终极从设计模式到抽象 与其说是如何写最少的代码不如说是如何只写真正有价值的代码。
通过良好的设计模式或者其变形体我们可以得到高内聚低耦合的代码这是一个非常好的思路。
另一个思路所有人都认同一点程序 算法 数据结构选择好正确的数据结构可以事倍功半比如说我们做类似文件夹需求的时候会想到使用链表或者树结构在做如如何高效的给用户发送生日短信时会想到用堆结构用当前时间对比堆中的最大值满足则继续迭代减少遍历等等。 这其实都是抽象或深或浅而已我最开始学习Java的时候老师会说一句话万物皆为对象我们来看看上面的技巧各自对应着什么
多返回值封装对象 泛型约束泛型封装对象的公共接口高度抽象函数式方法把方法当作一个对象重载对象方法行为的不断演化
所以如何只写真正有价值的代码官方一点的话就是把变化的抽象出来那么到底该怎么抽