Java SE 8 流库(一)
1. 流的作用
通过使用流,说明想要完成什么任务,而不是说明如何去实现它,将操作的调度留给具体实现去解决;
实例:假如我们想要计算某个属性的平均值,那么我们就可以指定数据源和属性,然后,流库就可以对计算进行优化;
1.1. 从迭代到流的操作
1.1.1. java.nio.file深度剖析
从java.nio.file提供的功能不难看出已经可以替换java.io.file所提供的功能;
1.1.1.1. java.nio.file的主要功能
1:对文件系统本身的操作,例如文件的复制,移除,删除,创建功能,创建软连接。
2:对文件系统的属性的进行操作,例如查看或修改 文件属性、操作权限、所属用户或用户组、最后修改时间,查看文件是否隐藏、文件的长度。
3:对文件系统进行遍历。
4:使用nio的方式查看和改变文件内容。
5:对文件或文件夹的创建,删除,修改事件进行监控。
1.1.1.2. java.nio.file提供常用方法
1:复制文件
copy(Path source,Path target,CopyOption... options) throws IOException
2:创建目录
createDirectories(Path dir,FileAttribute<?>... attrs) throws IOException
3:创建文件,path代表文件路径
createFile(Path path,FileAttribute<?>... attrs) throws IOException
4:创建连接,link代表目标连接,existing代表一个存在的文件
createLink(Path link,Path existing)throws IOException
5:删除文件
delete(Path path); deleteIfExists(Path path)
6:获取文件的BufferReader,BufferWriter
newBufferedReader(Path path, Charset cs), newBufferedWriter(Path path, Charset cs, OpenOption... options)
7:获取文件的InputStream,OutputStream
newInputStream(Path path, OpenOption... options),newOutputStream(Path path, OpenOption... options)
8:以字节和字符串形式读取文件
readAllBytes(Path path),readAllLines(Path path, Charset cs)
1.1.2. 实例
需求:对文档中的长单词进行计数
1.1.3. 传统方法
1 import java.nio.charset.StandardCharsets; 2 import java.nio.file.Files; 3 import java.nio.file.Paths; 4 import java.util.Arrays; 5 import java.util.List; 6 7 /** 8 * Created by Lenovo on 2017/12/14. 9 * 对文件中的长单词进行计数 10 */ 11 public class Demo01 { 12 13 private static final String filePath = "G:\\Idea\\src\\com\\itheima05\\Test_JavaSE\\Test_20171214\\word.txt"; 14 15 public static void main(String[] args) throws Exception { 16 17 //使用集合的方法实现 18 String contens = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8); 19 String[] ws = contens.split("\\PL+"); 20 //将数组转化为List集合 21 List<String> words = Arrays.asList(ws); 22 int count = 0; 23 for(String word:words){ 24 if(word.length()>6){ 25 count ++; 26 } 27 } 28 System.out.println(count); 29 } 30 }
1.1.4. 使用流处理
java.util.Collection<E>:
default Stream<E> stream() ----- 产生当前集合中所有元素的顺序流
default Stream<E> parallelStream() ----- 产生当前集合中所有元素的并行流
1 import java.nio.charset.StandardCharsets; 2 import java.nio.file.Files; 3 import java.nio.file.Paths; 4 import java.util.Arrays; 5 import java.util.List; 6 7 /** 8 * Created by Lenovo on 2017/12/14. 9 * 使用流对文档中的长单词进行计数 10 * 11 */ 12 public class Demo02 { 13 14 private static final String filePath = "G:\\Idea\\src\\com\\itheima05\\Test_JavaSE\\Test_20171214\\word.txt"; 15 16 public static void main(String[] args) throws Exception { 17 18 String contents = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8); 19 20 String[] ws = contents.split("\\PL+"); 21 //将数组转化为集合 22 List<String> words = Arrays.asList(ws); 23 //使用流 24 //Stream<T> filter(Predicate<? super T> predicate) 产生一个流,其中包含当前流中满足P的所有元素 25 //long count() 产生当前流中元素的数量,这个是一个终止操作 26 long count = words.stream() 27 .filter(w -> w.length() > 6) 28 .count(); 29 System.out.println("顺序流输出:"+count); 30 31 long count02 = words.parallelStream() 32 .filter(w -> w.length()>6) 33 .count(); 34 System.out.println("并行流输出:"+count02); 35 36 } 37 }
流的主要思想是:做什么而非怎么做;
以上实例:需要统计文档中的长度为6的单词
1.1.5. 流和集合的区别
1:流并不存储其元素;
2:流的操作不会修改其数据源
3:流的操作是尽可能惰性执行的
1.1.6. 流的操作流程
1:创建一个流
2:指定将初始流转化为其他流的中间操作,可能包含多个步骤(filter,产生新的流);
3:应用终止操作,从而产生结果
1.2. 流的创建
static <T> Stream<T> of(T... values) 返回一个元素为给定值的流
static <T> Stream<T> empty() 返回一个不包含任何元素的流
Optional<T> findFirst() 返回描述此流的第一个元素的可选项,如果流为空,则返回一个空的可选项。 如果流没有遇到命令,则可以返回任何元素。
static <T> Stream<T> generate(Supplier<T> s) 返回无限顺序无序流,其中每个元素由提供的供应商生成。 这适用于生成恒定流,随机元素流等。
static <T> Stream<T> iterate(T seed,UnaryOperator<T> f) 返回一个由函数f迭代应用到初始元素种子产生的无限序列有序流,产生由种子,f(种子),f(f(种子))等组成的流。Stream中的第一个元素(位置0)将是提供的种子。 对于n> 0,位置n处的元素将是对位置n-1处的元素应用函数f的结果。
java.util.regex.Pattern
public static Pattern compile(String regex) 将给定的正则表达式编译成模式。
public Stream<String> splitAsStream(CharSequence input) 根据给定的输入序列,围绕此模式的匹配创建一个流。
Java.util.File.Files
public static Stream<String> lines(Path path,Charset cs) throws IOException 从文件中读取所有行作为Stream。 与readAllLines不同,此方法不会将所有行读取到List中,而是在流被消耗时延迟地填充。
1 /** 2 * Created by Lenovo on 2017/12/16. 3 * static <T> Stream<T> of(T... values) 4 * 产生一个元素为给定值的流 5 */ 6 public class Demo03 { 7 8 private static final String filePath = "G:\\Idea\\src\\com\\itheima05\\Test_JavaSE\\Test_20171214\\word.txt"; 9 10 public static void main(String[] args) throws Exception { 11 12 String contents = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8); 13 //创建流(传入一个数组) 14 Stream<String> words = Stream.of(contents.split("\\PL+")); 15 long count = words.filter(w -> w.length() > 6) 16 .count(); 17 System.out.println(count); 18 19 //of方法具有可变长参数 20 Stream<String> song = Stream.of("gently", "down", "the", "stream"); 21 //取流中的第一个元素 22 String word = song.findFirst().get(); 23 System.out.println(word); 24 25 //创建不包含任何元素的流 26 Stream<String> empty = Stream.empty(); 27 List<String> list = empty.limit(1).collect(Collectors.toList()); 28 if(list.isEmpty()) { 29 System.out.println("list为空"); 30 } 31 32 //生成恒定流 33 Stream<String> sg = Stream.generate(() -> "Echo"); 34 String s = sg.findFirst().get(); 35 System.out.println("恒定流:"+s); 36 37 //生成一个随机流 38 Stream<Double> sgr = Stream.generate(Math::random); 39 Double dr = sgr.findFirst().get(); 40 System.out.println("随机流"+dr); 41 42 //产生无限序列 43 final int SIZE = 10; 44 Stream<BigInteger> si = Stream.iterate(BigInteger.ZERO, n -> n.add(BigInteger.ONE)); 45 List<BigInteger> NumList = si.limit(SIZE + 1).collect(Collectors.toList()); 46 for(int i = 0;i<NumList.size();i++){ 47 System.out.println(NumList.get(i)); 48 } 49 } 50 }
1.2.1. 实例
1.2.1.1. 问题1
public <T> void show(T t),void前面的泛型T是什么作用
public <T>这个T是个修饰符的功能,表示是个泛型方法,就像有static修饰的方法是个静态方法一样。
<T> 不是返回值,表示传入参数有泛型
public static <T>list<T> aslist(T...a)
第一个表示是泛型方法,第二个表示返回值是list类型,而这个list有泛型,只能存t类型的数据
1.2.1.1. 具体实例
1 public class Dem04 {
2 private static final String filePath = "G:\\Idea\\src\\com\\itheima05\\Test_JavaSE\\Test_20171214\\word.txt";
3 public static <T> void show(String title,Stream<T> stream){ 4 5 final int SIZE = 10; 6 List<T> tList = stream.limit(SIZE + 1) 7 .collect(Collectors.toList()); 8 System.out.print(title+":"); 9 for(int i=0;i<tList.size();i++){ 10 if(i>0){ 11 System.out.print(","); 12 } 13 if(i<SIZE){ 14 System.out.print(tList.get(i)); 15 }else{ 16 System.out.print("....."); 17 } 18 } 19 System.out.println(); 20 } 21 public static void main(String[] args) throws Exception { 22 23 String contents = new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8); 24 25 Stream<String> words = Stream.of(contents.split("\\PL+")); 26 show("words",words); 27 28 Stream<String> song = Stream.of("gently", "down", "the", "stream"); 29 show("song",song); 30 31 Stream<String> silence = Stream.empty(); 32 show("silence",silence); 33 34 Stream<String> generate = Stream.generate(() -> "Eche"); 35 show("generate",generate); 36 37 Stream<Double> randomNum = Stream.generate(Math::random); 38 show("randomNum",randomNum); 39 40 Stream<BigInteger> iterate = Stream.iterate(BigInteger.ZERO, n -> n.add(BigInteger.ONE)); 41 show("iterate",iterate); 42 43 Stream<String> ss = Pattern.compile("\\PL+").splitAsStream(contents); 44 show("ss",ss); 45 46 Stream<String> linesStream = Files.lines(Paths.get(filePath), StandardCharsets.UTF_8); 47 show("linesStream",linesStream); 48 } 49 }
输出结果:
1 words:In,my,dual,profession,as,an,educator,and,health,care,..... 2 song:gently,down,the,stream 3 silence: 4 generate:Eche,Eche,Eche,Eche,Eche,Eche,Eche,Eche,Eche,Eche,..... 5 randomNum:0.8545074280087089,0.05768740015609908,0.34845089835617316,0.9804483156381134,0.7893443687111327,0.5534594948929666,0.10749904759731743,0.32867498853912414,0.6739155442072872,0.6897019997934322,..... 6 iterate:0,1,2,3,4,5,6,7,8,9,..... 7 ss:In,my,dual,profession,as,an,educator,and,health,care,..... 8 linesStream:In my dual profession as an educator and health care provider,,I have worked with numerous children infected with the virus,that causes AIDS. The relationships that I have had with these,special kids have been gifts in my life. They have taught me so,many things, but I have especially learned that great courage,can be found in the smallest of packages. Let me tell you about Tyler.