Stream流
基本使用
Stream<String> myStream = Stream.of("a", "", "b", "c", "d");
myStream.filter(item -> item!="").map(String::toUpperCase).sorted().forEach(System.out::println); // ABCD
使用流注意點:
如果一個流沒有調用終端方法,那么流的其他操作都不會執行
終端方法如:count() collect() forEach()
流關閉
流用來操作文件的時候才需要手動關閉,單獨使用Stream不需要關閉
try (Stream<String> lines = Files.lines(Paths.get("C:\\Users\\26401\\Desktop\\demo.txt")).onClose(() -> System.out.println("流自動關閉了"))) {
lines.forEach(System.out::println);
}
平行流
處理順序:
上面介紹的例子都是順序流,但是如果對元素的順序不要求的時候可以使用平行流,開啟多核心多線程加速處理速度
List<Integer> list = Arrays.asList(1,2,3,4,5);
list.stream().forEach(System.out::println);
System.out.println("---------------");
list.parallelStream().forEach(System.out::println);
1 2 3 4 5
---------------
3 5 4 2 1
使用平行流注意點:
在開發網絡程序的時候,使用平行流會顯著降低性能,因為只有一個分支-合並流
除了這一點以外,平行流的性能根據cpu的核心數決定
Stream.of("a", "b").parallel();
Arrays.asList("a", "b").parallelStream();
流重用
流本身是不能重用的,但是可以使用iterator來實現重用
Iterable<Integer> iterable = () -> IntStream.range(1, 10).map(i -> ++i).iterator();
for (Integer item : iterable) {
System.out.println(item);
}
iterator轉換成流
Iterator<String> iterator = Arrays.asList("A", "B", "C").iterator();
Spliterator<String> spliterator = Spliterators.spliteratorUnknownSize(iterator, 0);
Stream<String> stream = StreamSupport.stream(spliterator, false);
stream.forEach(System.out::println);
分組計數
Stream
.of("a", "b", "a", "c")
.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
.entrySet()
.forEach(System.out::println);
a=2
b=1
c=1
無限流
方式一:
IntStream naturalNumbers = IntStream.iterate(1, x -> x + 1);
naturalNumbers.limit(5).forEach(System.out::println);
方式二:
Stream<Double> infiniteRandomNumbers = Stream.generate(Math::random);
infiniteRandomNumbers.limit(10).forEach(System.out::println);
流轉集合
方式一:
List<String> list = Stream.of("a", "b", "c").collect(Collectors.toList());
方式二:
List<String> list = Stream.of("a", "b", "c").collect(Collectors.toCollection(ArrayList::new));
方式三:
List<String> list = Stream.of("a", "b", "c").collect(Collectors.toCollection(() -> new ArrayList<>()));
壓縮流
List<String> list1 = Arrays.asList("a", "b");
List<String> list2 = Arrays.asList("c", "d");
List<String> list3 = Arrays.asList("e", "f");
List<String> joinList = Stream.of(list1, list2, list3).flatMap(Collection::stream).collect(Collectors.toList());
或者
List<String> joinList = Stream.of(list1, list2, list3).flatMap(List::stream).collect(Collectors.toList());
// ["a","b","c","d","e","f"]
統計數值流
IntSummaryStatistics
LongSummaryStatistics
DoubleSummaryStatistics
IntSummaryStatistics stats = Stream.of(1, 2, 3).mapToInt(x -> x).summaryStatistics();
stats.toString(); // IntSummaryStatistics{count=3, sum=6, min=1, average=2.000000, max=3}
集合轉換流遍歷
String[] names = { "Jon", "Darin", "Bauke", "Hans", "Marc" };
IntStream.range(0, names.length).mapToObj(i -> String.format("#%d %s", i + 1, names[i])).forEach(System.out::println);
流拼接
Stream.concat(Arrays.asList("a", "b", "c").stream(), Arrays.asList("d", "e", "f").stream());
reduce
reduce方法的作用類似於碼積木
OptionalInt result = IntStream.range(1, 10).reduce((b,l) -> b+l); // 45
int result = IntStream.range(1, 10).reduce(100, (b,l) -> b+l); // 145
使用流生成隨機字符串
SecureRandom 實例化開銷很大,可以使用setSeed重置
下面生成的隨機字符串只包含數字和字母
SecureRandom sr = new SecureRandom();
sr.setSeed(sr.generateSeed(20));
int length = 20;
Stream<Character> randomCharStream = sr.ints(Character.MIN_CODE_POINT,Character.MAX_CODE_POINT).mapToObj(i -> (char)i).filter(c -> c >= '0' && c <= 'z' && Character.isLetterOrDigit(c)).limit(length);
String randomString = randomCharStream.collect(StringBuilder::new, StringBuilder::append, StringBuilder::append).toString();
流的包裝流
幾種包裝流
PrintWriter 自動調用OutputStreamWriter,允許寫原始數據類型和字符串
OutputStreamWriter 將OutputStreams轉換成Writers從而來處理字符而不是字節
BufferedOutputStream/BufferedInputStream OutputStreams處理字節是一個一個的來處理的,這個流是一塊兒一塊兒來處理的
DeflaterOutputStream/DeflaterInputStream 壓縮數據
InflaterOutputStream/ InflaterInputStream 解壓數據
CipherOutputStream/ CipherInputStream 加密數據
DigestOutputStream/ DigestInputStream 解密數據
CheckedOutputStream/CheckedInputStream
DataOutputStream/ DataInputStream 寫字節
PrintStream 寫字節
包裝流寫字符到文件
FileOutputStream stream = new FileOutputStream("C:\\Users\\26401\\Desktop\\demo.txt");
try(PrintWriter writer = new PrintWriter(new BufferedOutputStream(stream))){
writer.write("我是包裝流寫的字符串");
}
加密和壓縮數據
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding"); // “算法/工作模式/填充模式”
SecretKey secretKey = new SecretKeySpec("abcdefghigklmnop".getBytes(), "AES");
cipher.init(Cipher.ENCRYPT_MODE, secretKey);
try(BufferedOutputStream outputStream = new BufferedOutputStream(new DeflaterOutputStream(new CipherOutputStream(new FileOutputStream("C:\\Users\\26401\\Desktop\\demo.txt"), cipher)));) {
outputStream.write("加密數據".getBytes());
}
Optional
Optional的常用方法
Optional的使用方式類似於Stream
區別在於,方法不會管有沒有調用終端方法,只會立即執行
ofNullable 如果值是null,則返回一個空的Optional
map
filter
get 獲取值
orElse 默認值
orElseGet 默認值
orElseThrow 默認拋出異常
Optional的基本使用
String value = "abc";
String str = Optional.ofNullable(value).map(String::toUpperCase).orElse("NONE"); // ABC
String value = null;
String str = Optional.ofNullable(value).orElseGet(() -> "defaultValue"); // defaultValue
String value = null;
String str = Optional.ofNullable(value).orElseThrow(IllegalArgumentException::new);
int value = 123;
int result = Optional.ofNullable(value).filter(item -> item == 123).get();
原始數據類型
OptionalDouble
OptionalInt
OptionalLong
結語
本文章是java成神的系列文章之一
如果你想知道,但是本文沒有的,請下方留言
我會第一時間總結出來並發布填充到本文