JAVA SE 8 学习笔记(六)杂项改进
来源:互联网 发布:淘宝旺铺免费模板 编辑:程序博客网 时间:2024/05/21 19:22
1. 字符串
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/170276496. 注解
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 SE 8 学习笔记(六)杂项改进
- Java SE 学习笔记(六)
- JAVA SE学习笔记
- JAVA SE 学习笔记
- java se 学习笔记
- Java学习笔记_000_杂项
- JAVA SE 8 学习笔记(一)lambda表达式
- JAVA SE 8 学习笔记(二)Stream API
- JAVA SE 8 学习笔记(三)使用lambda编程
- JAVA SE 8 学习笔记(五)并发增强
- Java SE 学习笔记 Lesson 8
- Java SE 学习笔记(一)
- Java SE 学习笔记(二)
- Java SE学习笔记-多线程
- Java SE学习笔记-集合
- Java SE学习笔记-IO
- Java SE学习笔记-GUI
- Java SE学习笔记(一)
- 伤寒杂病论白话文
- 14、Spring工具类之Resource
- Linux第三步交叉工具链arm-linux-gcc的安装
- 第11课:Spark Streaming源码解读之Driver中的ReceiverTracker架构设计以及具体实现彻底研究
- 【SHELL】监控系统信息CPU,磁盘,内存
- JAVA SE 8 学习笔记(六)杂项改进
- HDU 5699 货物运输 (二分 + 不等式判断 好题)
- 使用Toolbar/ActionBar自定义布局时,左侧/右侧有一段无法使用
- 怎样查看CentOS版本
- 方格取数问题[网络流24题之9]
- Fedora 普通用户和root用户切换
- swift 函数、函数类型及使用——swift学习(五)
- Oralce视图案列
- leetcode 175. Combine Two Tables