JAVA SE 8 学习笔记(六)杂项改进
2016-05-25 20:59
603 查看
1. 字符串
String提供了一个与split相反的join方法,将字符串通过分隔符组合起来.字符串可以来自于Array或者Iterable<? extends CharSequence>:
2. 数字类
7种数字类型的包装类提供了BYTES字段,用来表示该类型的长度
8种原始类型的包装类型,提供了静态的hashCode方法,用来返回与实例方法相同的hash码,省去装箱/拆箱。
Short, Integer, Long, Float, 和 Double提供了sum、max和min,用来在流操作中作为聚合函数使用。Boolean包含了logicalAnd, logicalOr, 和 logicalXor
Integer现在支持无符号数学计算, Byte 和 Short 类增加方法 toUnsignedInt。
Byte, Short, 和 Integer 增加方法 toUnsignedLong.
使用无符号数字,会丢失负数,并获得两倍的正数范围
Integer 和 Long 添加方法 compareUnsigned, divideUnsigned, 和
remainderUnsigned(求余)用来处理无符号值
Float和Double新增静态方法isFinite.当数字为正/负无穷大或者NAN(非数字时),该方法返回false,否则返回true
BigInteger 添加实例方法 (long|int|short|byte)ValueExact
返回对应的值, 当值不再目标范围内时抛出 ArithmeticException
3. 数学函数
Math类新增方法为:(add|subtract|multiply|increment|decrement|negate)Exact,参数为 int 和 long.这些方法可以进行精确计算,如果超过范围则会抛出异常。例如100000*100000会计算出错误结果1410065408(int型overflow),而multiplyExact(100000,
100000)会抛出异常。
floorMod
和 floorDiv旨在解决整型余数问题。在java中,如果n为负数,n%2为-1,而floorMod(position + adjustment, 12)总是返回一个0到11之间的数字。(对于负的除数,还是会返回负值)。floorDiv则返回0到12之间的数字。
4. 集合
1.集合接口新增方法参照下表:
![](https://img-blog.csdn.net/20160522203737304?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
2. 比较器
Comparator接口新增了许多有用的方法。
comparing可以接收一个键提取器。可以使用thenComparing来组合多个键提取器(按顺序排序)
也可以为提取的键指定一个比较器
两个方法都有避免装箱拆箱的形式,例如:
如果键函数包含Null,可以使用Comparator.nullFirst/nullLast方法决定null的位置
静态方法reverseOrder可以得到相反的排序。要点到任意比较器,可以调用实例方法reversed。
5. 使用文件
1.读取文件行的流
为了延迟读取一个文件中的行,可以使用Files.lines方法,它会产生一个包含字符串的流,每个字符串就是文件的一行
一旦包含password的第一行被找到,剩下的行就不会再被读取
Files.lines方法默认UTF-8编码。也可以设置charset来指定编码
Steam接口继承了AutoClosable,因此可以使用try-with-resources语法
当一个流调用其它流时,close方法也会递归调用
如果希望流关闭时收到通知,可以附加一个onClose方法
如果希望按行读取文件以外的来源,可以考虑使用BufferedReader.lines方法
注意:在这段代码中,关闭Steam并不会关闭Reader,因此需要将Reader放在try语句的头部
------------------------------------------------------------------
2. 遍历目录项的流
Files.list可以返回一个指定目录中项目的Steam<Path>对象
由于读取目录会涉及关闭一个系统资源,因此需要使用try语句
list方法不会进入子目录,要处理目录下的所有子目录,应该使用Files.walk方法
如果打算根据指定条件过滤walk方法的结果,应该使用find方法来代替,参数为一个predicate函数,参数为路径和一个BasicFileAttributes对象.find方法效率较高
-------------------------------------------------------
3. Base64编码
关于Base64编码的概念,请参照:http://blog.csdn.net/flycct/article/details/51445966
要进行Base64编码。可以使用Base64类的静态方法getEncoder, getUrlEncoder, 或者getMimeEncoder
该类包含了堆bytes数组或者NIO ByteBuffer进行编码的方法
也可以包装一个输出流,所有发送给它的数据都会自动进行编码
如果是使用基本的编码器,那么输出可能会包含反斜线“/”字符,但是如果使用URL编码器,那么输出的内容对URL来说是安全的。
MIME编码器会使用基本的字母数字产生BASE64输出,而且对MIME格式友好:每一行输出不超过76个字符,而且每行以“\r\n”符结束
参照博文:http://blog.csdn.net/chszs/article/details/17027649
6. 注解
1. JAVA SE 8允许可重复注解,实装内容包括两点:
1)将注解标注为@Repetable
2)提供一个容器主机
例如:
在表示factorial方法的元素上调用element.getAnnotation(TestCase.class)时返回为null
element.getAnnotationsByType(TestCase.class)则会返回包含TestCse注解的数组
---------------------------------------------------------------------------------
2. 可用于类型的注解
Java8中,可以在任何类型上标注注解
例如:
• 泛型类型参数: List<@NonNull String>, Comparator.<@NonNull String>reverseOrder().
• 用于array声明的任何位置: @NonNull String[][] words (words[i][j] is not null),
String @NonNull [][] words (words is not null), String[] @NonNull [] words (words[i] is
not null).
•父类和接口: class Image implements
@Rectangular Shape.
• 构造函数调用: new @Path String("/usr/bin").
• 类型转换和Instance of检查: (@Path String) input, if (input instanceof @Path String).
•定义抛出的异常: public Person read() throws @Localized IOException.
• 用于通配符和类型绑定: List<@ReadOnly ? extends Person>, List<? extends @ReadOnly> Person.
• 用于方法和构造函数引用: @Immutable Person::getName.
也有一些地方不能使用注解:
@NonNull String.class // 错误,不能标注class
import java.lang.@NonNull String; // 错误,不能标注import
另外,不能在注解上再加注解
推荐注解工具框架:
Checker Framework: http://types.cs.washington.edu/checker-framework/tutorial
---------------------------------------------------------------------------------
3. 方法参数反射
通过java.lang.reflect.Parameter类可以获取参数的名字,这样在某些参数名称与注解相同的情况下,可以将他们统一起来,省略代码
例如:
7. 其他
1.Null检查
Objects类新增两个静态的predicate方法,isNull和nonNull
这两个方法非常实用,例如:
steam.anyMatch(Objects::isNull); // 检查是否存在null
steam.filter(Objects::nonNull); // 获取所有非null对象
2. 正则表达式
命名捕获组 Matcher类的start、end和group方法,支持使用组名:
执行结果
05
5
7
Patten类增加splitAsStream方法,将一个CharSequence正则表达式进行分隔
a
b
c
asPredicate方法,可以用来过滤匹配的字符串
b
c
String提供了一个与split相反的join方法,将字符串通过分隔符组合起来.字符串可以来自于Array或者Iterable<? extends CharSequence>:
String joined = String.join("/", "usr", "local", "bin"); // "usr/local/bin" System.out.println(joined); String ids = String.join(", ", ZoneId.getAvailableZoneIds()); System.out.println(ids); // All time zone identifiers, separated by commas
2. 数字类
7种数字类型的包装类提供了BYTES字段,用来表示该类型的长度
8种原始类型的包装类型,提供了静态的hashCode方法,用来返回与实例方法相同的hash码,省去装箱/拆箱。
Short, Integer, Long, Float, 和 Double提供了sum、max和min,用来在流操作中作为聚合函数使用。Boolean包含了logicalAnd, logicalOr, 和 logicalXor
Integer现在支持无符号数学计算, Byte 和 Short 类增加方法 toUnsignedInt。
Byte, Short, 和 Integer 增加方法 toUnsignedLong.
使用无符号数字,会丢失负数,并获得两倍的正数范围
Integer 和 Long 添加方法 compareUnsigned, divideUnsigned, 和
remainderUnsigned(求余)用来处理无符号值
Float和Double新增静态方法isFinite.当数字为正/负无穷大或者NAN(非数字时),该方法返回false,否则返回true
BigInteger 添加实例方法 (long|int|short|byte)ValueExact
返回对应的值, 当值不再目标范围内时抛出 ArithmeticException
3. 数学函数
Math类新增方法为:(add|subtract|multiply|increment|decrement|negate)Exact,参数为 int 和 long.这些方法可以进行精确计算,如果超过范围则会抛出异常。例如100000*100000会计算出错误结果1410065408(int型overflow),而multiplyExact(100000,
100000)会抛出异常。
floorMod
和 floorDiv旨在解决整型余数问题。在java中,如果n为负数,n%2为-1,而floorMod(position + adjustment, 12)总是返回一个0到11之间的数字。(对于负的除数,还是会返回负值)。floorDiv则返回0到12之间的数字。
4. 集合
1.集合接口新增方法参照下表:
2. 比较器
Comparator接口新增了许多有用的方法。
comparing可以接收一个键提取器。可以使用thenComparing来组合多个键提取器(按顺序排序)
Arrays.sort(people, Comparator.comparing(Person::getLastName) .thenComparing(Person::getFirstName));
也可以为提取的键指定一个比较器
Arrays.sort(people, Comparator.comparing(Person::getName, (s, t) -> Integer.compare(s.length(), t.length())));
两个方法都有避免装箱拆箱的形式,例如:
Arrays.sort(people, Comparator.comparingInt(p -> p.getName().length()));
如果键函数包含Null,可以使用Comparator.nullFirst/nullLast方法决定null的位置
Comparator.comparing(Person::getMiddleName(), Comparator.nullsFirst(...))
静态方法reverseOrder可以得到相反的排序。要点到任意比较器,可以调用实例方法reversed。
5. 使用文件
1.读取文件行的流
为了延迟读取一个文件中的行,可以使用Files.lines方法,它会产生一个包含字符串的流,每个字符串就是文件的一行
Stream<String> lines = Files.lines(path); Optional<String> passwordEntry = lines.filter(s -> s.contains("password")).findFirst();
一旦包含password的第一行被找到,剩下的行就不会再被读取
Files.lines方法默认UTF-8编码。也可以设置charset来指定编码
Steam接口继承了AutoClosable,因此可以使用try-with-resources语法
当一个流调用其它流时,close方法也会递归调用
try (Stream<String> filteredLines = Files.lines(path).filter(s -> s.contains("password"))) { Optional<String> passwordEntry = filteredLines.findFirst(); ... }
如果希望流关闭时收到通知,可以附加一个onClose方法
try (Stream<String> filteredLines = Files.lines(path).onClose(() -> System.out.println("Closing")) .filter(s -> s.contains("password"))) { ... }如果流读取文件发生IOException,则会包装异常为UncheckedIOException抛出
如果希望按行读取文件以外的来源,可以考虑使用BufferedReader.lines方法
try (BufferedReader reader = new BufferedReader(new InputStreamReader(url.openStream()))) { Stream<String> lines = reader.lines(); ... }
注意:在这段代码中,关闭Steam并不会关闭Reader,因此需要将Reader放在try语句的头部
------------------------------------------------------------------
2. 遍历目录项的流
Files.list可以返回一个指定目录中项目的Steam<Path>对象
由于读取目录会涉及关闭一个系统资源,因此需要使用try语句
try (Stream<Path> entries = Files.list(pathToDirectory)) { ... }
list方法不会进入子目录,要处理目录下的所有子目录,应该使用Files.walk方法
try (Stream<Path> entries = Files.walk(pathToRoot)) { // Contains all descendants, visited in depth-first order }可以使用Files.walk(pathToRoot, depth)来指定访问目录树的深度
如果打算根据指定条件过滤walk方法的结果,应该使用find方法来代替,参数为一个predicate函数,参数为路径和一个BasicFileAttributes对象.find方法效率较高
-------------------------------------------------------
3. Base64编码
关于Base64编码的概念,请参照:http://blog.csdn.net/flycct/article/details/51445966
要进行Base64编码。可以使用Base64类的静态方法getEncoder, getUrlEncoder, 或者getMimeEncoder
该类包含了堆bytes数组或者NIO ByteBuffer进行编码的方法
Base64.Encoder encoder = Base64.getEncoder(); String original = username + ":" + password; String encoded = encoder.encodeToString(original.getBytes(StandardCharsets.UTF_8));
也可以包装一个输出流,所有发送给它的数据都会自动进行编码
Path originalPath = ..., encodedPath = ...; Base64.Encoder encoder = Base64.getMimeEncoder(); try (OutputStream output = Files.newOutputStream(encodedPath)) { Files.copy(originalPath, encoder.wrap(output)); }如果要进行解码,只需要将这些操作颠倒过来
Path encodedPath = ..., decodedPath = ...; Base64.Decoder decoder = Base64.getMimeDecoder(); try (InputStream input = Files.newInputStream(encodedPath)) { Files.copy(decoder.wrap(input), decodedPath); }
如果是使用基本的编码器,那么输出可能会包含反斜线“/”字符,但是如果使用URL编码器,那么输出的内容对URL来说是安全的。
MIME编码器会使用基本的字母数字产生BASE64输出,而且对MIME格式友好:每一行输出不超过76个字符,而且每行以“\r\n”符结束
参照博文:http://blog.csdn.net/chszs/article/details/17027649
6. 注解
1. JAVA SE 8允许可重复注解,实装内容包括两点:
1)将注解标注为@Repetable
2)提供一个容器主机
例如:
@Repeatable(TestCases.class) @interface TestCase { String params(); String expected(); } @interface TestCases { TestCase[] value(); }重复注解的使用:
@TestCase(params="4", expected="24") @TestCase(params="0", expected="1") public static long factorial(int n) { ... }当用户提供多个@TestCase注解时,它们会自动包装为@TestCases注解
在表示factorial方法的元素上调用element.getAnnotation(TestCase.class)时返回为null
element.getAnnotationsByType(TestCase.class)则会返回包含TestCse注解的数组
---------------------------------------------------------------------------------
2. 可用于类型的注解
Java8中,可以在任何类型上标注注解
例如:
• 泛型类型参数: List<@NonNull String>, Comparator.<@NonNull String>reverseOrder().
• 用于array声明的任何位置: @NonNull String[][] words (words[i][j] is not null),
String @NonNull [][] words (words is not null), String[] @NonNull [] words (words[i] is
not null).
•父类和接口: class Image implements
@Rectangular Shape.
• 构造函数调用: new @Path String("/usr/bin").
• 类型转换和Instance of检查: (@Path String) input, if (input instanceof @Path String).
•定义抛出的异常: public Person read() throws @Localized IOException.
• 用于通配符和类型绑定: List<@ReadOnly ? extends Person>, List<? extends @ReadOnly> Person.
• 用于方法和构造函数引用: @Immutable Person::getName.
也有一些地方不能使用注解:
@NonNull String.class // 错误,不能标注class
import java.lang.@NonNull String; // 错误,不能标注import
另外,不能在注解上再加注解
推荐注解工具框架:
Checker Framework: http://types.cs.washington.edu/checker-framework/tutorial
---------------------------------------------------------------------------------
3. 方法参数反射
通过java.lang.reflect.Parameter类可以获取参数的名字,这样在某些参数名称与注解相同的情况下,可以将他们统一起来,省略代码
例如:
Person getEmployee(@PathParam("dept") Long dept, @QueryParam("id") Long id)可以省略为以下代码,而通过参数名字来获取注解的value
Person getEmployee(@PathParam Long dept, @QueryParam Long id)不幸的是,为了获取文件中的信息,必须使用javac -parameters SourceFile.java的方式来编译源码
7. 其他
1.Null检查
Objects类新增两个静态的predicate方法,isNull和nonNull
这两个方法非常实用,例如:
steam.anyMatch(Objects::isNull); // 检查是否存在null
steam.filter(Objects::nonNull); // 获取所有非null对象
2. 正则表达式
命名捕获组 Matcher类的start、end和group方法,支持使用组名:
Pattern pattern = Pattern.compile("^(?<year>\\d{4})-(?<month>\\d{2})-\\d{2}$"); Matcher matcher = pattern.matcher("2016-05-25"); if(matcher.matches()) { System.out.println(matcher.group("month")); System.out.println(matcher.start("month")); System.out.println(matcher.end("month")); }
执行结果
05
5
7
Patten类增加splitAsStream方法,将一个CharSequence正则表达式进行分隔
Stream<String> words = Pattern.compile("\\d").splitAsStream("a1b2c3"); words.forEach(v -> System.out.println(v));执行结果
a
b
c
asPredicate方法,可以用来过滤匹配的字符串
Stream<String> words = Pattern.compile("\\d").splitAsStream("a1b2c3"); words.filter(Pattern.compile("[bc]").asPredicate()).forEach(v -> System.out.println(v));执行结果
b
c
相关文章推荐
- Java 实现导出excel表 POI
- java设计模式-组合模式
- java基础 -- 多线程总结(一)--基本概念
- 【转】spring bean的生命周期
- java的若干问题(4)——java常用类库
- 广义表及其Java代码实现
- 广义表及其Java代码实现
- spring boot 之如何在两个页面之间传递值
- java mkdir()和mkdirs()区别
- Java垃圾收集机制
- java.lang.NoSuchMethodError: 属于jar包冲突
- 【转】Java生产者消费者模式的实现的几种方法
- Java 单例模式
- Spring事务配置
- Java并发编程实战 第二,三,四章
- MyEclipse配置进行Hibernate逆映射
- 学习java使用数组编写学生管理系统
- java设计模式-桥接模式
- java 内存映射处理大文件
- Spring定时任务之Quartz