Java核心技术·卷二·笔记

第一章:Java8的流库

Java8引入的用来以“做什么而非怎么做”的方式的处理集合

1.1 从迭代到流的操作

package com.package1;import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;public class Test {public static void main(String[] args) throws IOException {var contents = new String(Files.readAllBytes(Paths.get("alice.txt")),StandardCharsets.UTF_8);List<String> words = List.of(contents.split("\\PL+"));//里面是一个regex正则表达式,表示的是非字母,split的意思是分裂,这个方法会更具后面的regex返回一个String数组int count = 0;for(String w:words){if(w.length() > 12){count++;}}//使用流long count2 = words.stream().filter(w -> w.length() > 12).count();//将串行的stream修改成parallelStream就可以让流库以并行的方式来执行过滤和计数long count3 = words.parallelStream().filter(w -> w.length() > 12).count();}
}

流与集合是有显著的差异的:

  1. 流并不储存元素。
  2. 流的操作不会修改其数据源
  3. 流的操作是尽可能的惰性执行的。这意味着可以操作无限流

流遵循了“做什么而非怎么做的原则”,描述了需要做什么,而交给Java本身去实现,给了Java的优化空间,相对于自行指定操作流程,更方便也更快捷

  • 创建流
  • 转换流
  • 应用终止操作,从而产生结果

1.2 流的创建

可以用Collection接口的的stream方法将任何的集合转换成流。也可以使用静态的Stream.of方法

Stream<String> words= Stream.of(contains.split("\\PL+"));
//of具有可变长度,可以构建具有任意数量引元的流
Stream<String> song = Stream.of("gently","down","the","stream");
//使用Array.stream(array,from,to)可以使用数组的一部分元素来创建一个流
//创建一个不包含任何元素的流
Stream<String> silence = Stream.empty();

在操作流的时候,并没有对流背后的集合进行操作.因此对流的引元进行删除等操作是错误而且毫无意义的.

package com.package1;import java.io.IOException;
import java.math.BigInteger;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Iterator;
import java.util.List;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import java.util.stream.StreamSupport;public class Test {public static void main(String[] args) throws IOException {//下面会展示大部分的创建流的操作Path path = Paths.get("../gutenberg/alice30.txt");var contents = new String(Files.readAllBytes(path),StandardCharsets.UTF_8);Stream<String> words = Stream.of(contents.split("\\PL+"));//of方法会产生一个元素为给定值的流//static <T> Stream<T> of(T... values);show("words",words);Stream<String> song = Stream.of("gently","down","the","stream");show("song",song);Stream<String> silence = Stream.empty();show("silence",silence);Stream<String> echos= Stream.generate(()->"Echo");//generate方法产生一个无限流,它是通过不断调用函数s来构建的//static <T> Stream<T> generate(Supplier<T> s)show("echos",echos);Stream<Double> randoms = Stream.generate(Math::random);//也可以直接用Java给定的闭包的方法引用show("randoms",randoms);Stream<BigInteger> integers = Stream.iterate(BigInteger.ONE,n-> n.add(BigInteger.ONE));//产生一个无限流,它的原始包括seed,在seed上调用f产生的值,在前一个元素上调用f产生的值//可以加一个hasNext谓语来指定终止// static <T> Stream<T> iterate(T seed,UnaryOPerator<T> f)// static <T> Stream<T> iterate(T seed,Predicate<? super T> hasNext,UnaryOPerator<T> f)show("integers",integers);//Java API中大量的方法都可以产生流,例如下面这个方法会将contents里面的字符串分割为一个个单词Stream<String> wordAnotherWay = Pattern.compile("\\PL+").splitAsStream(contents);show("wordAnotherWay",wordAnotherWay);//Files.lines方法会返回一个包含了文件中所有行的Streamtry(Stream<String> lines = Files.lines(path,StandardCharsets.UTF_8)){show("lines",lines);}Iterable<Path> iterable = FileSystems.getDefault().getRootDirectories();//如果所持有的iterable对象不是集合可以通过下面的调用将其转换成一个流Stream<Path> rootDirectories = StreamSupport.stream(iterable.spliterator(),false);show("rootDirections",rootDirectories);Iterator<Path> iterator = Paths.get("/usr/share/dict/words").iterator();//如果是Iterator对象,可以使用下面的语句将其转换成流Stream<Path> pathComponents = StreamSupport.stream(Spliterators.spliteratorUnknownSize(iterator, Spliterator.ORDERED),false);show("pathComponents",pathComponents);}public static <T> void show(String title, Stream<T> stream){final int SIZE= 10;List<T> firstElements = stream.limit(SIZE+1).collect(Collectors.toList());System.out.print(title+": ");for(int i = 0; i < firstElements.size(); i++){if(i > 0){System.out.print(", ");}if(i < SIZE){System.out.print(firstElements.get(i));}else{System.out.print("...");}}System.out.println();}
}

1.3 filter,map和flatMap方法

Stream<T> filter(Predicate<? super T> predicate);
//产生一个流,它包含当前流中所有满足谓语条件的元素
<R> Stream<R> map(Function<? super T,? extends R> mapper);
//产生一个流,它包含将mapper应用于当前流中所有元素所产生的结果
<R> Stream<R> flatmap(Function<? super T, ? extends Stream<? extends R>> mapper);
//产生一个流,它不光实现map的功能,还会将结果连接到一起(注意,这里的每一个结果的都是一个流,即将流连接)

1.4 抽取子流和集合流

Stream<T> limit(long maxSize);
//产生一个流,其中包含了当前流中最初的maxSize个元素
Stream<T> skip(long n);
//舍弃前n个
Stream<T> takeWhile(Predicate<? super T> predicate);
//产生满足条件predicate的流
Stream<T> dropWhile(Predicete<? super T> predicate);
//产生一个流,元素为不满足predicate条件的元素之外的元素
static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b);
//连接

1.5 其他的流转换

Stream<T> distinct();
//去重
Stream<T> sorted();
Stream<T> sorted(Comparator<? super T> comparator);
//排序,可以加入自己的排序规格
Stream<T> peek(Consumer<? super T> action);
//产生一个流,与原流相同,获取其中每个元素都会将其传递给action;
package com.package1;import java.util.Comparator;
import java.util.stream.Stream;public class Test {public static void main(String[] args){Stream<String> uniqueWords = Stream.of("Job","Job","Tom","Job").distinct();uniqueWords.peek(e -> System.out.println(" "+e));//注意,这是没有任何输出的,因为peek是一个中间操作,而没有终止操作,就只是“流过去”罢了,加一个例如toArray这种终止操作,就会有输出了Stream<String> longestFirst = words.stream().sorted(Comparator.comparing(String::length).reversed());Object[] powers = Stream.iterate(1.0,p -> p*2).peek(e -> System.out.println(" "+e)).limit(20).toArray();}
}

1.6 简单约简

约简是一种终结操作(terminal operation)

它们返回的并非Stream而是Optional类型。Optional类型是一种缺少返回值的更好的方式

以下都是终结操作:
Optional<T> max(Comparator<? super T> comparator);
Optional<T> min(Comparator<? super T> comparator);
返回max,min,
Optional<T> findFirst();
Optional<T> findAny();
返回第一个或者任意一个元素,如果流为空,返回空的Optional;
boolean anyMacth(Predicate<? super T> predicate);
boolean allMacth(Predicate<? super T> predicate);
boolean nonMacth(Predicate<? super T> predicate);
任意,所有,没有 元素满足谓语返回true

1.7 Optional 类型

1.7.1 获取Optional的值

可以再没有任何匹配的时候使用默认值

String result = optionalString.orElse("");

也可以从配置文件里面加载默认值

String result = optionalString.orElseGet(() -> System.getProperty("myapp.default"));

也可以抛出异常

String result = optionalString.orElseThrow(IllegalStateException);

1.7.2 消费Optional的值

opionalValue.ifPresent(v->Process v);

例如如果该值存在的情况下将其添加到某个集当中,就可以调用

optionalValue.ifPresent(v -> result.add(v));
//or:
optinalValue.ifPresent(result::add);

也可以实现在满足的时候执行一种动作,在不满足的时候执行另一种动作

optionalValue.ifPresentOrElse(
v->System.out.println("Found"+v),
()->logger.warning("No Match")
);

1.7.3 管道化Optional值

可以使用map来转化Optional内部的值

Optional<String> transformed = optionalString.map(String::toUpperCase);

可以直接用map来进行相关操作

optionalValue.map(result::add);
//还可以添加filter
Optional<String> transformed = optionalString.filter(s -> s.length() >= 8).map(String::toUpperCase);

可以使用or方法将空的Optional替换成一个可替代的Optional。它将以惰性计算

Optional<String> result = optionalString.or(() -> alternatives.stream().findFirst());

1.7.4 不适合使用Optional值的方式

对于Optional的使用,应该遵循以下原则:

  • Optional类型的变量永远都不应该为null
  • 不要使用Optional类型域,这只会额外多出来一个对象(所谓域,其实是“field”的翻译, 也就是我们常说的字段,或者说是属性)
  • 不要在集合中放置Optional对象,而且不要将他作为map的键。应该直接收集其中的值

调用Optional的isPresent等方法反而会将问题处理变得复杂

1.7.5 创建Optional的值

static <T> Optional<T> of(T value);
static <T> Optional<T> ofNullable(T value);
//两个方法都会用value的值产生一个Optional,第一个方法在value为空时会抛出NullPointerException异常,第二个会自动调用empty方法产生一个空的Optional
static <T> Optional<T> empty();

1.7.6 用flatMap创建Optional值的函数

<U> Optional<U> flatMap(Function<? super T, ? extends Optional<? extends U>> mapper);
将mapper应用于当前Optional值所产生的结果,或者在当前Optional为空时,返回一个空Optional

1.7.7 将Optional转换为流

stream将Optional方法转化成一个或者两个的Stream对象

package com.package1;import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Optional;public class Test {public static void main(String[] args) throws IOException {var contents = new String(Files.readAllBytes(Paths.get("src/com/package1/demo.txt")), StandardCharsets.UTF_8);List<String> wordlist = List.of(contents.split("\\PL+"));Optional<String> optionalValue = wordlist.stream().filter(s -> s.contains("fred")).findFirst();System.out.println(optionalValue.orElse("No Word") +" contains fred");Optional<String> optionalString = Optional.empty();String result = optionalString.orElse("N/A");System.out.println("result: "+result);result = optionalString.orElseGet(() -> Locale.getDefault().getDisplayName());System.out.println("result: "+result);try{result = optionalString.orElseThrow(IllegalStateException::new);System.out.println("result: "+result);}catch (Throwable t){t.printStackTrace();}optionalValue = wordlist.stream().filter(s -> s.contains("red")).findFirst();optionalValue.ifPresent(s -> System.out.println(s+"contains red"));var results = new HashSet<String>();optionalValue.ifPresent(results::add);Optional<Boolean> added = optionalValue.map(results::add);System.out.println(added);System.out.println(inverse(4.0).flatMap(Test::squareRoot));System.out.println(inverse(-1.0).flatMap(Test::squareRoot));System.out.println(inverse(0.0).flatMap(Test::squareRoot));Optional<Double> result2 = Optional.of(-4.0).flatMap(Test::inverse).flatMap(Test::squareRoot);System.out.println(result2);}public static Optional<Double> inverse(Double x){return x == 0 ? Optional.empty() : Optional.of(1 / x);}public static Optional<Double> squareRoot(Double x){return x < 0 ? Optional.empty() : Optional.of(Math.sqrt(x));}
}

1.8 收集结果

package com.package1;import com.sun.source.tree.Tree;import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class Test {public static void main(String[] args) throws IOException {Iterator<Integer> iter = Stream.iterate(0, n -> n+1).limit(10).iterator();while(iter.hasNext()){System.out.println(iter.next());}Object[] numbers = Stream.iterate(0, n -> n+1).limit(10).toArray();System.out.println("Object array:" + numbers+Arrays.toString(numbers));//注意,由于无法在运行的时候创建泛型数组,所以表达式stream.toArray会返回一个Object数组try{var number = (Integer) numbers[0];System.out.println("number:" + number);System.out.println("The following state will throw an Exception");var number2 = (Integer[]) numbers;//Object[]强制类型转换会由于无法识别转换前后是否属于子类或者同一类而报错}catch (ClassCastException e){System.err.println(e);}Integer[] number3 = Stream.iterate(0, n -> n+1).limit(10).toArray(Integer[]::new);//传入构造方法就可以指定类型System.out.println("Integer Array: "+ number3);Set<String> noVowelSet = noVowels().collect(Collectors.toSet());show("noVowelSet",noVowelSet);TreeSet<String> noVowelTreeSet = noVowels().collect(Collectors.toCollection(TreeSet::new));show("noVowelTreeSet",noVowelTreeSet);String result = noVowels().limit(10).collect(Collectors.joining());System.out.println("Joining: "+result);result = noVowels().limit(10).collect(Collectors.joining(", "));System.out.println("Joining with commas "+result);IntSummaryStatistics summary = noVowels().collect(Collectors.summarizingInt(String::length));double averageWorldLength = summary.getAverage();double maxWorldLength = summary.getMax();System.out.println("averageWorldLength: "+averageWorldLength);System.out.println("maxWorldLength: "+maxWorldLength);System.out.println("Foreach: ");noVowels().limit(10).forEach(System.out::println);}public static Stream<String> noVowels() throws IOException {var contains = new String(Files.readAllBytes(Paths.get("src/com/package1/demo.txt")), StandardCharsets.UTF_8);List<String> wordList = List.of(contains.split("\\PL+"));Stream<String> words = wordList.stream();return words.map(s -> s.replaceAll("[aeiouAEIOU]", ""));}public static <T > void show (String label, Set< T > set){System.out.print(label+": "+set.getClass().getName());System.out.println("["+set.stream().limit(10).map(Object::toString).collect(Collectors.joining(", ")));}
}

1.9 收集到映射表中

package com.package1;import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;public class Test {public static void main(String[] args) {Map<Integer, String> idToName = people().collect(Collectors.toMap(Person::getId,Person::getName));System.out.println("idToName:"+idToName);Map<Integer, Person> idToPerson = people().collect(Collectors.toMap(Person::getId, Function.identity()));System.out.println("idToPerson: "+idToPerson.getClass().getName()+idToPerson);idToPerson = people().collect(Collectors.toMap(Person::getId,Function.identity(),(existingValue, newValue) -> {throw new IllegalStateException();}, TreeMap::new));//第三个引元阐述了如果原有的键值和新的键值产生冲突的解决方法(实际上默认的解决就是抛出异常),第四个引元使得本该为Map的本方法生产了TreeMap.System.out.println("idToPerson: "+idToPerson.getClass().getName()+idToPerson);Stream<Locale> locals = Stream.of(Locale.getAvailableLocales());Map<String,String> languageNames = locals.collect(Collectors.toMap(Locale::getDisplayLanguage, l -> l.getDisplayLanguage(l),(existingValue, newValue) -> existingValue,TreeMap::new));System.out.println("languageNames: "+ languageNames);locals = Stream.of(Locale.getAvailableLocales());Map<String, Set<String>> countryLanguageSets = locals.collect(Collectors.toMap(Locale::getDisplayCountry, l -> Set.of(l.getDisplayLanguage()), (a,b) ->{Set<String> union = new HashSet<>(a);union.addAll(b);return union;}));System.out.println("countryLanguageSets"+countryLanguageSets);}public static class Person {private int id;private String name;public Person(int id, String name) {this.id = id;this.name = name;}public int getId() {return id;}public String getName() {return name;}public String toString() {return getClass().getName() + "[id=" + id + "name=" + name + "]";}}public static Stream<Person> people() {return Stream.of(new Person(100, "Peter"), new Person(1002, "Paul"), new Person(1003, "Mary"));}
}
result:
=================================================================================
D:\Devlop\Environment\JDK-15.0.2\bin\java.exe "-javaagent:C:\Program Files\Devlop\IDE\JetBrains\IntelliJ IDEA 2021.1.2\lib\idea_rt.jar=50157:C:\Program Files\Devlop\IDE\JetBrains\IntelliJ IDEA 2021.1.2\bin" -Dfile.encoding=UTF-8 -classpath C:\Users\MuRuo\Desktop\Dev\IDEA\JavaRelearn\out\production\JavaRelearn com.package1.Test
idToName:{100=Peter, 1002=Paul, 1003=Mary}
idToPerson: java.util.HashMap{100=com.package1.Test$Person[id=100name=Peter], 1002=com.package1.Test$Person[id=1002name=Paul], 1003=com.package1.Test$Person[id=1003name=Mary]}
idToPerson: java.util.TreeMap{100=com.package1.Test$Person[id=100name=Peter], 1002=com.package1.Test$Person[id=1002name=Paul], 1003=com.package1.Test$Person[id=1003name=Mary]}
languageNames: {=, 上索布语=hornjoserbšćina, 下索布语=dolnoserbšćina, 世界语=esperanto, 东桑海语=Koyraboro senni, 中库尔德语=کوردیی ناوەندی, 中文=中文, 丹麦语=dansk, 乌克兰语=українська, 乌兹别克语=o‘zbek, 乌尔都语=اردو, =========此处略去很多字============马库阿语=Makua, 马恩语=Gaelg, 马拉加斯语=Malagasy, 马拉地语=मराठी, 马拉雅拉姆语=മലയാളം, 马来语=Melayu, 马耳他语=Malti, 马赛语=Maa, 马赞德兰语=مازرونی, 高棉语=ខ្មែរ, 鲁巴加丹加语=Tshiluba}
countryLanguageSets{巴西=[西班牙语, 葡萄牙语], 泰国=[泰语], =[, 旺杜语, 乌兹别克语, 桑布鲁语, 爪哇语, 宿务语, 隆迪语, 索加语, 克罗地亚语, =========此处略去很多字============科威特=[阿拉伯语], 牙买加=[英语], 世界=[阿拉伯语, 依地文, 普鲁士语, 世界语, 沃拉普克语, 国际语, 英语]}Process finished with exit code 0

1.10 群组和分区

将相同的值群组成组的方法

Map<String,List<Locale>> countryToLocales = locales.collect(Collector.groupingBy(Locale::getCountry));
//称Locale::getCountry为分类函数

当分类函数是断言函数(即返回值为Boolean的函数时,使用partitioningBy方法更高效

Map<Boolean, List<Locale>> englishAndOtherLocales = locales.collect(Collectors.partitingBy(l -> l.getLanguage().equals("en")));
List<Locale> englishLocales = englishAndOtherLocales.get(true);

1.11 下游收集器

groupingBy方法产生的映射表的每个值都是一个列表,下游收集器用于处理这些列表

package com.package1;import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;import static java.util.stream.Collectors.*;
//静态引入public class Test {public static void main(String[] args) throws IOException{Stream<Locale> locales = Stream.of(Locale.getAvailableLocales());locales = Stream.of(Locale.getAvailableLocales());Map<String,Set<Locale>> countryToLocaleSet = locales.collect(groupingBy(Locale::getCountry,toSet()));System.out.println("countryToLocaleSet: "+countryToLocaleSet);locales = Stream.of(Locale.getAvailableLocales());Map<String,Long> countryToLocaleCounts = locales.collect(groupingBy(Locale::getCountry,counting()));System.out.println("countryToLocaleCounts: "+countryToLocaleCounts);Stream<City> cities = readCities("cities.txt");Map<String,Integer> stateToCityPopulation = cities.collect(groupingBy(City::getState,summingInt(City::getPopulation)));System.out.println("stateToCityPopulation: "+ stateToCityPopulation);cities = readCities("cities.txt");Map<String,Optional<String>> stateToLongestCityName = cities.collect(groupingBy(City::getState,mapping(City::getName,maxBy(Comparator.comparing(String::length)))));locales = Stream.of(Locale.getAvailableLocales());Map<String,Set<String>> countryToLanguages = locales.collect(groupingBy(Locale::getDisplayCountry,mapping(Locale::getDisplayLanguage,toSet())));cities = readCities("cities.txt");Map<String,IntSummaryStatistics> stateToCityPopulationSummary = cities.collect(groupingBy(City::getState,summarizingInt(City::getPopulation)));System.out.println(stateToCityPopulationSummary.get("NY"));cities = readCities("cities.txt");Map<String,String> stateToCityNames = cities.collect(groupingBy(City::getState,reducing("",City::getName,(s,t) -> s.length() == 0 ? t : s + "," +t)));cities = readCities("cities.txt");stateToCityNames = cities.collect(groupingBy(City::getState,mapping(City::getName,joining(","))));}public static class City{private String name;private String state;private int population;public City(String name, String state, int population) {this.name = name;this.state = state;this.population = population;}public String getName() {return name;}public String getState() {return state;}public int getPopulation() {return population;}}public static Stream<City> readCities(String filename) throws IOException{return Files.lines(Paths.get(filename)).map(l -> l.split(", ")).map(a -> new City(a[0],a[1],Integer.parseInt(a[2])));}
}

1.12 约简操作

对于v1 op v2 , v2 op v3, v3 op v4, …, vn op vn+1…,称op为约简操作,在实际中,例如求和,成绩,字符串连接,求最大值和最小值,求集合的并与交等等(但是需要op操作是可结合的,例如减法操作不满足置换性,就不能使用约简操作)

通常会有一个幺元e使得 e op x = x ,例如在加法操作中幺元是0

如果流为空,则会返回幺元的值,而非Optional类

List<Integer> values = ...;
Optional<Integer> sum = values.stream().reduce((x,y) -> x+y);
//也可以直接写成 reduce(Integer::sum);
List<Integer> values = ...;
Integer sum = values.stream().reduce(0,(x,y) -> x+y);
int result = words.reduce(0,(total,word) -> total + world.length,(total1,total2) -> total1+total2);
//第一个lambda表达式表示将每个单词的个数相加,第二个lambda表达式指出如果多线程操作,将每个线程的结果再相加形成最终结果

1.13 基本类型流

IntStream,LongStream,DoubleStream .... 用来直接存储基本类型值,而无需使用包装器
package com.package1;import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;public class Test {public static void main(String[] args) throws IOException{IntStream is1 = IntStream.generate(() ->(int)(Math.random()*100));show("is1",is1);IntStream is2 = IntStream.range(5,10);show("is2",is2);IntStream is3 = IntStream.rangeClosed(5,10);//10 is includedshow("is3",is3);Path path  = Paths.get("./src/com/package1/demo.txt");var contents = new String((Files.readAllBytes(path)), StandardCharsets.UTF_8);Stream<String> words = Stream.of(contents.split("\\PL+"));IntStream is4 = words.mapToInt(String::length);//mapTo...方法按照传入的lambda表达式对每一个元素进行映射操作,转化成基本类型流show("is4",is4);var sentences = "\uD835\uDD46 is the set of octonions";System.out.println(sentences);IntStream codes =sentences.codePoints();//CharSequence接口的codePoints方法,生成由字符的UnionCode码或者UTF-16编码机制的码元构成的IntStreamSystem.out.println(codes.mapToObj(c -> String.format("%X",c)).collect(Collectors.joining()));Stream<Integer> integers = IntStream.range(0,100).boxed();//boxed方法将基本类型流转换为对象流IntStream is5 = integers.mapToInt(Integer::intValue);show("is5",is5);}public static void show(String title, IntStream stream){final int SIZE = 10;int[] firstElements = stream.limit(SIZE+1).toArray();System.out.print(title+": ");for(int i = 0; i < firstElements.length; i++){if(i > 0){System.out.print(", ");}if(i < SIZE){System.out.print(firstElements[i]);}else{System.out.print("...");}}System.out.println();}}

1.14 并行流

看不懂,以后再来细啃

Java核心技术·卷二·第一章笔记相关推荐

  1. Java 8实战 第一章笔记

    流是一系列数据项,一次只生成一项. Java 8新增的编程概念:流处理,通过API来传递代码,函数式编程. ::语法:"把这个方法作为值". 函数式编程风格:编写把函数作为一等值的 ...

  2. Java核心技术卷一 -第九章:集合

    系列文章目录 Java核心技术卷一 -第一章:java"白皮书"的关键术语 Java核心技术卷一 -第三章:数据类型 Java核心技术卷一 -第三章:变量与常量 Java核心技术卷 ...

  3. 《Java 核心技术 卷1》 笔记 第五章 继承(3)

    5.1.6 抽象类 有时候我们无法说出具体是什么,只能用于标识一个类型,比如图形,就可作为抽象类.虽然无法具体描述图形,但是图形通常都有面积.周长.这种时候就可用抽象类标识. 抽象类使用abstrac ...

  4. 《Java核心技术 卷Ⅰ》读书笔记一

    Java核心技术·卷 I(原书第10版) 作者: [美] 凯.S.霍斯特曼(Cay S. Horstmann) 出版社: 机械工业出版社 原作名: Core Java Volume I - Funda ...

  5. Spring第一章笔记

    Spring第一章笔记 第一步: 配置pom文件导入依赖 <dependencies><dependency><groupId>org.springframewor ...

  6. 计算机应用基础自学手写笔记,计算机应用基础第一章笔记.docx

    计算机应用基础第一章笔记 1.计算机工具的变迁 2.计算机的发展过程 3.冯.诺依曼计算机的工作原理 4.计算机系统的硬件和软件组成 5.计算机的性能指标 6.影响计算机的性能因素 7.数据在计算机中 ...

  7. 《Python深度学习》第一章笔记

    <Python深度学习>第一章笔记 1.1人工智能.机器学习.深度学习 人工智能 机器学习 深度学习 深度学习的工作原理 1.2深度学习之前:机器学习简史 概率建模 早期神经网络 核方法 ...

  8. 《Java核心技术卷一》读书笔记

    <Java核心技术卷一>读书笔记 对象与类 类 类是构造对象的模板.蓝图.由类构造对象的过程称为类的实例. 对象的数据叫做实例域,操作数据的过程叫做方法 对于每个特定的类实例(对象)都要一 ...

  9. 【智能计算系统笔记】第一章笔记及课后习题

    第一章笔记及课后习题 笔记 课后习题 1. 简述强人工智能和弱人工智能的区别. 2. 简述人工智能研究的三个学派. 3. 一个有两个输入的单个神经元构成的感知机能完成什么任务? 4. 深度学习的局限性 ...

最新文章

  1. App.config的典型应用
  2. 160个Crackme035
  3. mysql在线检测失败_一则线上MySql连接异常的排查过程
  4. 删除WSS卸载后遗留的数据库
  5. mysql csdn 知乎_CSDN 怎么样?
  6. spring事务分类简述
  7. mysql 线程id_查找MySQL线程中死锁的ID的方法
  8. 又是一个秋天~~~~
  9. 给tomcat指定JDK
  10. 超好用的卸载工具——geek
  11. CuteFTP Pro v8.3.1 (Build 08.07.2008.1) - patch - PakMan / Team SnD
  12. 企业微信客户端web页面调试
  13. Java中除数能否为0
  14. 斗战神与服务器断开响应,win10系统玩斗战神游戏掉线的设置办法
  15. vue多次引用组件,减少每个页面import的方法
  16. 过了面试入职被排挤,离职是最坏的做法!
  17. 1.JS高级红宝书程序设计之JS的嵌入方式
  18. HbuilderX 运行app项目不成功
  19. R语言逻辑回归的预测概率怎么算
  20. Linux centos环境 安装谷歌浏览器

热门文章

  1. 程序员防内卷小游戏3之游戏打包
  2. 计算机和网络设备的辐射强,计算机网络设备信息辐射泄漏与抑制
  3. Python中colorbar全色表
  4. html字重怎么设置,CSS 字重 font-weight
  5. 转:Redis监控技巧
  6. MySQL多表查询大全(超精确)
  7. Linux学习入门-------------------------VMvare与镜像的安装与配置
  8. 超详细的纯CSS的照片墙特效
  9. 阿里云EasyExcel读写excel表数据
  10. 白话中台战略2:中台到底长啥样?