##Java7 新特性 ##
1. 二进制类型
Java SE 7中, 整数类型(byte, short, int以及long) 也可以使用二进制数系来表示。
要指定一个二进制字面量,可以给二进制数字添加前缀 0b 或者 0B。下面的示例展示了一些二进制字面量:
// 一个8位的'byte'值:
byte aByte = (byte)0b00100001;
// 一个16位的'short'值:
short aShort = (short)0b1010000101000101;
// 几个32位的'int'值:
int anInt1 = 0b10100001010001011010000101000101;
int anInt2 = 0b101;
int anInt3 = 0B101; // B可以是大写或者小写.
// 一个64位的'long'值.注意"L"后缀:
long aLong = 0b1010000101000101101000010100010110100001010001011010000101000101L;
2. 数值类中使用下划线
下划线使数值可读性更高,尤其在二进制中
int i = 1_000_000; // 一百万
int i = 0b1000_0000; // 2^7 128
3. 在switch中使用字符串
switch 中终于可以使用字符串了 π_π
String week = "星期二";
switch (week) {
case "星期一":
// ....
break;
case "星期二":
// ....
break;
case "星期三":
// ....
break;
default:
break;
}
4. 泛型实例创建时的类型推断
Java SE 6 或 以前
Map<String, List<String>> myMap = new HashMap<String, List<String>>();
在Java SE 7中, 你可以使用一个空的类型参数集合 (<>)代替构造器的参数化类型:
Map<String, List<String>> myMap = new HashMap<>();
5. try-with-resource 异常处理
// JDK1.7之前我们必须在finally块中手动关闭资源,否则会导致资源的泄露
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(path));
return br.readLine();
} catch (IOException e) {
e.printStackTrace();
} finally {//必须在这里关闭资源
if (br != null)
br.close();
}
return null;
// JDK1.7之后就可以使用try-with-resources,不需要我们在finally块中手动关闭资源
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
br.readLine();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
6. 处理多种类型的异常
JAVA SE 7 以前 每个 catch 块中都包含重复代码:
catch (IOException ex) {
// 模拟异常处理
syso("发生异常");
syso("处理异常");
syso("记录日志");
catch (SQLException ex) {
// 模拟异常处理
syso("发生异常");
syso("处理异常");
syso("记录日志");
}
JAVA SE 7
catch (IOException|SQLException ex) {
syso("发生异常");
syso("处理异常");
syso("记录日志");
}
##Java 8 新特性##
1. 函数式接口
函数式接口(Functional Interface)是Java 8对一类特殊类型的接口的称呼。
这类接口只定义了唯一的抽象方法的接口, 因此最开始也就做SAM类型的接口(Single Abstract Method)。
粗俗: 函数式接口即只有一个抽象方法的接口
下面这个接口只有一个抽象方法, 这种接口就叫函数式接口
public interface MyInterface {
public abstract void run();
}
// 如下这种不叫函数式接口
public interface MyInterface {
public abstract void run1();
public abstract void run2();
}
为接口添加注解 @FunctionalInterface ,可以让编译器校验只能有一个抽象方法
// 如下会报错
@FunctionalInterface
public interface MyInterface {
public abstract void run1();
public abstract void run2();
}
// 表示接口是函数式接口,所以只能有一个抽象方法
@FunctionalInterface
public interface MyInterface {
public abstract void run();
}
2. 静态方法
Java 8中可以定义静态方法。一个或者多个静态方法并且不会影响接口成为函数式接口
例如:
@FunctionalInterface
interface MyInterface {
public abstract void run();
public static int sum(int a , int b) {
return a + b;
}
}
// 使用
public static void main(String[] args) {
MyInterface.sum(10, 20);
}
3. 默认方法
Java 8中允许接口实现方法, 而不是简单的声明, 这些方法叫做默认方法,使用特殊的关键字default。
// 定义
@FunctionalInterface
interface MyInterface {
public abstract void run();
public default int sum(int a , int b) {
return a + b;
}
}
// 使用 (创建接口的实现类,或匿名类)
MyInterface my = new MyInterface(){
@Override
public void run() {
System.out.println("什么都不做");
}
};
my.sum(10, 20);
4. Lambda表达式 (读音:兰姆达)
- 匿名类型最大的问题就在于其冗余的语法。有人戏称匿名类型导致了“高度问题”(height problem)
// 让我们先实现一个线程
new Thread(new Runnable() {
@Override
public void run() {
// 实现...
}
});
- lambda表达式是匿名方法,它提供了轻量级的语法,从而解决了匿名内部类带来的“高度问题”。
new Thread(() -> {
// 实现...
});
- lambda 表达式只可用在函数式接口上,因为函数式接口只有一个抽象方法 (JAVA可以识别出来)
例如
java.lang.Runnable
java.util.concurrent.Callable
java.util.Comparator
- lambda 表达式语法解释
1. 最最基本的语法(无参无返回值)
Runnable r = new Runnable() {}
lambda 写法
Runnable r = () -> {}
2. 有返回值得情况
接口类型 a = () -> {return x};
接口类型 a = () -> x;
例如
public interface MyInterface {
int test();
}
MyInterface m = () -> {return 10;};
MyInterface m = () -> 10;
3. 有参数,有返回值
(int x, int y) -> x + y
(int x, int y) -> {return x + y;}
5. Stream (流)
- Stream是 Java 8新增加的类,用来补充集合类。
- Stream 入门例子
List<Integer> list = Arrays.asList(1, 4, 2, 4, 6, 7, 2, 1);
// 获取stream对象
Stream<Integer> stream = list.stream();
// 遍历流 (lambda表达式让流使用起来更简单)
stream.forEach(i -> {
System.out.println(i);
});
// 方法引用语法 (等同上面,是一种简写方式)
stream.forEach(System.out::println);
- Stream 常用的方法
1. forEach
forEach遍历流的每一个元素,执行指定的action。它是一个终点操作。
例如
Stream.of(1,2,3,4,5).forEach(System.out::println);
Arrays.asList(1,2,3,4,5).stream().forEach(System.out::println);
2. distinct
distinct保证输出的流中包含唯一的元素,它是通过Object.equals检查是否包含相同的元素。
List<String> l = Stream.of("a","b","c","b")
.distinct()
.collect(Collectors.toList());
System.out.println(l); //[a, b, c]
3. reduce
reduce是常用的一个方法,事实上很多操作都是基于它实现的。
// 求和
Optional<Integer> sum = Stream.of(1, 2, 3, 4, 5).reduce((a, b) -> a + b);
System.out.println(sum.get());
4. max、min、count
返回流中最大,最小,数量
5. filter
filter返回的流中只包含满足断言(predicate)的数据。
// 过滤奇数
List<Integer> l = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8)
.stream().filter(i -> i % 2 == 0)
.collect(Collectors.toList());
System.out.println(l); // [2, 4, 6, 8]
6. sorted
// 一行代码实现升序
Stream.of(2,4,67,8,3,1,4,6,87,2,39,8).sorted().forEach(System.out::println);
System.out.println("============");
// 一行代码实现降序
Stream.of(2,4,67,8,3,1,4,6,87,2,39,8).sorted((a,b) -> b-a).forEach(System.out::println);
> 官方翻译文档
> http://www.cnblogs.com/figure9/archive/2014/10/24/4048421.html
1. 二进制类型
Java SE 7中, 整数类型(byte, short, int以及long) 也可以使用二进制数系来表示。
要指定一个二进制字面量,可以给二进制数字添加前缀 0b 或者 0B。下面的示例展示了一些二进制字面量:
// 一个8位的'byte'值:
byte aByte = (byte)0b00100001;
// 一个16位的'short'值:
short aShort = (short)0b1010000101000101;
// 几个32位的'int'值:
int anInt1 = 0b10100001010001011010000101000101;
int anInt2 = 0b101;
int anInt3 = 0B101; // B可以是大写或者小写.
// 一个64位的'long'值.注意"L"后缀:
long aLong = 0b1010000101000101101000010100010110100001010001011010000101000101L;
2. 数值类中使用下划线
下划线使数值可读性更高,尤其在二进制中
int i = 1_000_000; // 一百万
int i = 0b1000_0000; // 2^7 128
3. 在switch中使用字符串
switch 中终于可以使用字符串了 π_π
String week = "星期二";
switch (week) {
case "星期一":
// ....
break;
case "星期二":
// ....
break;
case "星期三":
// ....
break;
default:
break;
}
4. 泛型实例创建时的类型推断
Java SE 6 或 以前
Map<String, List<String>> myMap = new HashMap<String, List<String>>();
在Java SE 7中, 你可以使用一个空的类型参数集合 (<>)代替构造器的参数化类型:
Map<String, List<String>> myMap = new HashMap<>();
5. try-with-resource 异常处理
// JDK1.7之前我们必须在finally块中手动关闭资源,否则会导致资源的泄露
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(path));
return br.readLine();
} catch (IOException e) {
e.printStackTrace();
} finally {//必须在这里关闭资源
if (br != null)
br.close();
}
return null;
// JDK1.7之后就可以使用try-with-resources,不需要我们在finally块中手动关闭资源
try (BufferedReader br = new BufferedReader(new FileReader(path))) {
br.readLine();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
6. 处理多种类型的异常
JAVA SE 7 以前 每个 catch 块中都包含重复代码:
catch (IOException ex) {
// 模拟异常处理
syso("发生异常");
syso("处理异常");
syso("记录日志");
catch (SQLException ex) {
// 模拟异常处理
syso("发生异常");
syso("处理异常");
syso("记录日志");
}
JAVA SE 7
catch (IOException|SQLException ex) {
syso("发生异常");
syso("处理异常");
syso("记录日志");
}
##Java 8 新特性##
1. 函数式接口
函数式接口(Functional Interface)是Java 8对一类特殊类型的接口的称呼。
这类接口只定义了唯一的抽象方法的接口, 因此最开始也就做SAM类型的接口(Single Abstract Method)。
粗俗: 函数式接口即只有一个抽象方法的接口
下面这个接口只有一个抽象方法, 这种接口就叫函数式接口
public interface MyInterface {
public abstract void run();
}
// 如下这种不叫函数式接口
public interface MyInterface {
public abstract void run1();
public abstract void run2();
}
为接口添加注解 @FunctionalInterface ,可以让编译器校验只能有一个抽象方法
// 如下会报错
@FunctionalInterface
public interface MyInterface {
public abstract void run1();
public abstract void run2();
}
// 表示接口是函数式接口,所以只能有一个抽象方法
@FunctionalInterface
public interface MyInterface {
public abstract void run();
}
2. 静态方法
Java 8中可以定义静态方法。一个或者多个静态方法并且不会影响接口成为函数式接口
例如:
@FunctionalInterface
interface MyInterface {
public abstract void run();
public static int sum(int a , int b) {
return a + b;
}
}
// 使用
public static void main(String[] args) {
MyInterface.sum(10, 20);
}
3. 默认方法
Java 8中允许接口实现方法, 而不是简单的声明, 这些方法叫做默认方法,使用特殊的关键字default。
// 定义
@FunctionalInterface
interface MyInterface {
public abstract void run();
public default int sum(int a , int b) {
return a + b;
}
}
// 使用 (创建接口的实现类,或匿名类)
MyInterface my = new MyInterface(){
@Override
public void run() {
System.out.println("什么都不做");
}
};
my.sum(10, 20);
4. Lambda表达式 (读音:兰姆达)
- 匿名类型最大的问题就在于其冗余的语法。有人戏称匿名类型导致了“高度问题”(height problem)
// 让我们先实现一个线程
new Thread(new Runnable() {
@Override
public void run() {
// 实现...
}
});
- lambda表达式是匿名方法,它提供了轻量级的语法,从而解决了匿名内部类带来的“高度问题”。
new Thread(() -> {
// 实现...
});
- lambda 表达式只可用在函数式接口上,因为函数式接口只有一个抽象方法 (JAVA可以识别出来)
例如
java.lang.Runnable
java.util.concurrent.Callable
java.util.Comparator
- lambda 表达式语法解释
1. 最最基本的语法(无参无返回值)
Runnable r = new Runnable() {}
lambda 写法
Runnable r = () -> {}
2. 有返回值得情况
接口类型 a = () -> {return x};
接口类型 a = () -> x;
例如
public interface MyInterface {
int test();
}
MyInterface m = () -> {return 10;};
MyInterface m = () -> 10;
3. 有参数,有返回值
(int x, int y) -> x + y
(int x, int y) -> {return x + y;}
5. Stream (流)
- Stream是 Java 8新增加的类,用来补充集合类。
- Stream 入门例子
List<Integer> list = Arrays.asList(1, 4, 2, 4, 6, 7, 2, 1);
// 获取stream对象
Stream<Integer> stream = list.stream();
// 遍历流 (lambda表达式让流使用起来更简单)
stream.forEach(i -> {
System.out.println(i);
});
// 方法引用语法 (等同上面,是一种简写方式)
stream.forEach(System.out::println);
- Stream 常用的方法
1. forEach
forEach遍历流的每一个元素,执行指定的action。它是一个终点操作。
例如
Stream.of(1,2,3,4,5).forEach(System.out::println);
Arrays.asList(1,2,3,4,5).stream().forEach(System.out::println);
2. distinct
distinct保证输出的流中包含唯一的元素,它是通过Object.equals检查是否包含相同的元素。
List<String> l = Stream.of("a","b","c","b")
.distinct()
.collect(Collectors.toList());
System.out.println(l); //[a, b, c]
3. reduce
reduce是常用的一个方法,事实上很多操作都是基于它实现的。
// 求和
Optional<Integer> sum = Stream.of(1, 2, 3, 4, 5).reduce((a, b) -> a + b);
System.out.println(sum.get());
4. max、min、count
返回流中最大,最小,数量
5. filter
filter返回的流中只包含满足断言(predicate)的数据。
// 过滤奇数
List<Integer> l = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8)
.stream().filter(i -> i % 2 == 0)
.collect(Collectors.toList());
System.out.println(l); // [2, 4, 6, 8]
6. sorted
// 一行代码实现升序
Stream.of(2,4,67,8,3,1,4,6,87,2,39,8).sorted().forEach(System.out::println);
System.out.println("============");
// 一行代码实现降序
Stream.of(2,4,67,8,3,1,4,6,87,2,39,8).sorted((a,b) -> b-a).forEach(System.out::println);
> 官方翻译文档
> http://www.cnblogs.com/figure9/archive/2014/10/24/4048421.html