java8 stream 并发

Submitted by Lizhe on Fri, 04/14/2017 - 15:02

 

先随便写个代码打印1o个随机数,顺便加上parallel

package com.stream;

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

Lambda表达式的线程安全问题与闭包

Submitted by Lizhe on Fri, 04/14/2017 - 11:07

 

Lambda表达式所使用的外部变量不能是可变的局部变量 (也就是说它只能接受成员变量,final的局部变量和参数)

下面例子中的test就是一个外部变量

实际上就是说,它不能接受非final的保存在线程祯中的变量, 等等, 这句话看起来是不是有点眼熟, 为什么会有这样的限制呢

首先这个Lambda表达式是运行在一个独立的子线程中,当这个线程运行时,它实际上拿到的是一个原始变量的副本(一个拷贝)

类似于经典的swap(a,b)函数,我相信每一个在大学学过c语言的人都碰到过这个考试题 :P

还记得Java8推出之前的热点问题么, java是否需要引入闭包, 那么Lambda表达式是否符合闭包的含义呢

闭包本身是一个函数,一段代码,一个可以被执行的逻辑, 它可以随意访问自身外部的其他变量,

Java8的Lambda表达式和匿名类也可以做类似于闭包的事情,比如下面这个例子里的Lambda表达式就访问了一个外部变量test

一般情况下很多人接触闭包都是通过javascript, javascript的闭包实际上是通过子函数来实现的,因为在javascript中只有一个函数的子函数才能访问这个函数的局部变量

Java8 stream reduce

Submitted by Lizhe on Thu, 04/13/2017 - 16:39

 

虽然上次我说filter方法有点类似于hadoop的Mapreduce,不过实际上stream提供了一个自己的方法也叫 reduce

通常情况下这个方法接受两个参数, 一个初始值,一个Lambda表达式

下面是一个求和的例子

 int total = students.stream().map(Student::getScore).reduce(0,(a,b)->a+b);

上面这个等价于 Optional<Integer> sum = students.stream().map(Student::getScore).reduce(Integer::sum);

首先我们把Students的list用map方法取出score, 然后初始值设置成0, 第一个值是0+80=80, 第二个值是80+81=161... 以此类推

取乘积的话可以用         int product = students.stream().map(Student::getScore).reduce(1,(a,b)->a*b);

这个方法还有一个不需要提供初始值的版本

Java8 stream api

Submitted by Lizhe on Thu, 04/13/2017 - 12:16

实际上java8的stream指导思想几乎跟hadoop的Mapreduce如出一辙, 

都是基于一个数据流,然后做reduce,最后进行一次聚合的操作,这种模型完美的匹配了多线程

import static静态导入是JDK1.5中的新特性。一般我们导入一个类都用 import com.....ClassName;而静态导入是这样:import static com.....ClassName.*;这里的多了个static,还有就是类名ClassName后面多了个 .* ,意思是导入这个类里的静态方法。当然,也可以只导入某个静态方法,只要把 .* 换成静态方法名就行了。然后在这个类中,就可以直接用方法名调用静态方法,而不必用ClassName.方法名 的方式来调用

下面的例子如果想使用多线程只需要改成

List<Student> stus3 = students.parallelStream().filter(s->s.getScore()>90).collect(toList());

Vagrant不能挂在共享文件夹

Submitted by Lizhe on Wed, 04/12/2017 - 13:52

 

vagrant突然不能挂在共享文件夹了, 提示我版本不匹配,这些文件夹全部不能映射

 config.vm.synced_folder "ansible", "/home/vagrant/ansible", owner: "vagrant", group: "vagrant"
 config.vm.synced_folder "deployment", "/home/vagrant/deployment", owner: "vagrant", group: "vagrant"
 config.vm.synced_folder "preparation", "/home/vagrant/preparation", owner: "vagrant", group: "vagrant"
 config.vm.synced_folder "C:/Users/Lizhe/.m2", "/root/.m2", owner: "vagrant", group: "vagrant"

安装增强插件以后好了

vagrant plugin install vagrant-vbguest

FSDataInputStream seek

Submitted by Lizhe on Tue, 04/11/2017 - 22:13

 

package hadoop.cat;

import java.net.URI;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;

使用 FileSystem 读取文件

Submitted by Lizhe on Tue, 04/11/2017 - 16:35

不能使用URLStreamHandlerFactory时,可以通过FileSystem来读取文件的输入流

public static FileSystem get(Configuration conf) throws IOException 
public static FileSystem get(URI uri, Configuration conf) throws IOException 
public static FileSystem get(URI uri, Configuration conf, String user) throws IOException

conf对象用于封装服务器或者客户端信息,它需要使用 core-site.xml来指定

如果没有指定相关的配置,默认会使用本地文件系统, 下面是我本地的配置

 

$ vim ~/hadoop/etc/hadoop/core-site.xml