文档章节

java8函数式编程

j
 javayfs
发布于 2016/06/03 08:19
字数 1259
阅读 35
收藏 0

   Java8引入了很多"让人眼前一亮"的一些新特性,本文先介绍函数式编程(java8 lambda)。

   首先想象这么一种应用,在工作生活中总是有可能需要处理一个功能:查询一张表的全部数据,然后将这张表的数据遍历,每条记录写入csv文件。

也许你会采用下面的做法:

//do not do this

public class ExportTabDAO{

@Override

public void persistAll() 

throws DataAccessException{

String sql = "select * from ${sometable}";

JdbcTemplate jdbcTemplate = ...;

CsvWriter csvWriter = ...;

jdbcTemplate.query(sql, new RowCallbackHandler() {

@Override

public void processRow(ResultSet rs) throws SQLException {

//下面开始获取表的若干属性

    String name = rs.getString(1);

String title = rs.getString(2);

//handle代码和dao层耦合,不是好的设计

csvWriter.writeNext(new String[]{name, title});

}

});

}

}

   这种做法有什么不好的呢:在Dao数据处理层,不应该把handle耦合在代码当中(如果下次你还需要把这张表的数据写入到excel,又要在processRow里面写一定处理了,甚至可能需要在重新写一个方法)。

   那么正确的做法应该是怎样的呢,我们应该把name,title封装成一个对象,把这个对象交给上层的处理(这里上层的处理不是确定的,有一些上层的处理是要处理成csv,有些上层的处理是要处理成excel)

下面来看一种改善的做法:

public void persistAll(Consumer<Entity> function) 

throws DataAccessException{

String sql = "select * from ${sometable}";

JdbcTemplate jdbcTemplate = ...;

//CsvWriter csvWriter = ...; 这里不再需要处理csv了

jdbcTemplate.query(sql, new RowCallbackHandler() {

@Override

public void processRow(ResultSet rs) throws SQLException {

//下面开始获取表的若干属性

    String name = rs.getString(1);

String title = rs.getString(2);

//将这几个属性交由上层处理,解决耦合问题

function.apply(new Entity(name,title));

}

});

}

在上层这样子调用:

ExportTabDAO dao = ...;

dao.persistAllBiblios(entity -> {

//do something entity

});

在上面的例子中,我们看到了一种全新的语法和全新的类Consumer(位于java.util.function包中,是一个函数式接口 function interface)

这种全新的语法在java8中称为lambda表达式(可以简单理解为匿名内部类语法糖),也就是没有这种语法糖我们需要下面的写法:

dao.persistAllBiblios(new Consumer<Entity>() {

@Override

public void accept(Entity t{

//do something t

}

});

   当然jdk8中的lambda还可以做很多便捷的操作,例如,你是一名商店的管理者,想知道自己卖的每件商品,在2016年5月的销售记录中,每个商品分类的销售数量的话,有一种做法是使用sql统计出来。但是也可以在程序中计算每个分类的销售数量,如下。

final List<String> types = new ArrayList<String>(10000);

//从销售日志表中获取获取每个商品的分类,加入到list中

Map<String, Integer> map = types.stream().collect(Collectors

.groupingBy(s -> s, Collectors.summingInt(s -> 1)) );

List<Entry<String, Integer>> list = new ArrayList<>(map.entrySet());

//按销量排序取出前几个分类

list.sort(Comparator.comparing((Entry<String, Integer> entry) -> entry.getValue()).reversed());

list.stream().limit(100).forEach(System.out::println);

   还有一个例子是我们在开发中有时需要遍历一个项目中的access.log文件(访问日志文件,以此来处理一些操作),用jdk8可以很方便的处理:

Files.list(new File("F:/access/logs").toPath()).forEach(file -> {

Files.lines(file).forEach(line -> {

//dosomething line

});

});

  下面是jdk8 Collectors 的在线api,也有介绍jdk8一些函数编程的使用方式:

https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html

  jdk8中还引入了一些简化并发操作的api,下面是一个小例子:

JdbcTemplate jdbcTemplate = ...;

//统计各个地区的某个日志表日志量总数

List<Pair<String,Integer>> list = Arrays.asList("gz","zj","wh")

.parallelStream().map(area -> {

String tableName = area + "_log";

int cnt = jdbcTemplate.queryForObject(

"select count(1) from " + tableName, Integer.class);

return Pair.of(area, cnt);

}).collect(Collectors.toList());

   ps:目前项目用到jdk8的地方还是很多,此文先开个头,并且推荐一本书《java8函数式编程》,下次再补上相关介绍内容(下次更新大概要等到猴年马月吧)

   ps:jdk8中java.util.collection集合更新的Stream api太值得学习了

   ps:目前个人觉得此篇文章的example太少了

近期学习计划以及文章更新计划如下:

1.继续学习jdk8的一些特性并更新到文章中。

2.个人用一段时间系统学习了一些推荐系统的相关知识,有空补上。

3.maven项目管理相关,学了父子项目,项目聚合,目前未整理相关知识。

4.solr,ElasticSearch这两个搜索引擎框架也要系统学习下了。

5.Spring boot,以及spring-boot-session项目的学习

6.Nginx,redis

7.学习一门可能和技术无关的知识,目前个人正在看一本head first出版的《深入浅出pmp》的书,只看了一点点(该书主要内容范围为项目管理)

8.设计模式、函数式编程持续性学习(目前认为还是要多看源码,然后完善自己的一些代码设计)

9.系统学习一门orm框架例如mybatis

10.安全控制框架也有可能在新项目中应用上,比如可能要学习一下spring-security,以及看下spring-boot如何整合spring-security

© 著作权归作者所有

j
粉丝 4
博文 12
码字总数 11740
作品 0
广州
程序员
私信 提问
一起来学Java8(一)——函数式编程

在这篇文章中,我们将了解到在Java8下如何进行函数式编程。 函数式编程 所谓的函数式编程就是把函数名字当做值进行传递,然后接收方拿到这个函数名进行调用。 首先来看下JavaScript如何进行函...

tanghc
2019/10/19
84
0
Java 8 新语法习惯 (提倡使用有帮助的编码)

表达能力强是函数式编程的优势之一,但是这对于我们的代码意味着什么呢?在这部分内容中,我们将比较命令式和函数式代码的示例,判断这两种的表达能力和简洁性的能力。我们还能够了解到这些品...

晁东洋
2018/01/08
0
0
Java8新特性:函数式接口@FunctionalInterface使用说明

Java8新特性:接口静态方法与默认方法 Java8新特性:函数式接口@FunctionalInterface使用说明 Java8新特性:方法引用 Java8新特性:函数式编程 我们常用的一些接口Callable,Runnable,Comparato...

键走偏锋
2018/08/05
341
0
java8 -函数式编程之四个基本接口

不管lambda表达式还是Stream流式编程,Function、Consumer、Supplier、Predicate 四个接口是一切函数式编程的基础。下面我们详细学习这四个巨头, interface Supplier<T> 该接口的中文直译是...

细肉云吞
2018/12/24
573
0
java8 -函数式编程之Lambda表达式

1 前言 java 8已经流行很多年了,springboot 2、spring 5 等开源代码也已经开始使用大量函数式编程。为了跟上潮流和看懂一些源码,下面我们一起学习java8的函数式编程。由于在lambda的学习过...

细肉云吞
2018/12/20
517
0

没有更多内容

加载失败,请刷新页面

加载更多

iStatistica Pro for Mac(系统监控工具) v1.1.2

iStatistica Mac破解版推荐给大家!iStatistica Pro Mac是一款功能强大的系统监控工具,实时监控CPU,内存,网络,磁盘卡,帮你轻松删除不需要的文件和文件夹,释放电脑内存,提升运行速度。...

云不若
20分钟前
6
0
Vim和Ctags提示和技巧[关闭]

我刚刚使用我的Vim(或者更确切地说是gVim)安装了Ctags (以帮助进行C ++开发),并希望找到您最喜欢的命令,宏,快捷方式,以及随之而来的提示...... 分享你最好的武器库。 在Vim开发中你会...

技术盛宴
23分钟前
8
0
tensorlfow安装

系统环境 nv-jetson-nano-sd-card-image-r32.3.1.zip 1 基本工具安装 默认安装了python 3.6.8,需要安装如下基本软件 sudo apt updatesudo apt install curlcurl https://bootstrap.pyp...

JosiahMg
23分钟前
5
0
彻底修改maven项目工程的名称

1

观海562
42分钟前
6
0
整数反转(力扣)

整数反转 一、题目描述 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。 示例 1: 输入: 123 输出: 321 示例 2: 输入: -123 输出: -321 示例 3: 输入: 120 输出: 21 ...

迪迪迪王
52分钟前
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部