java8新特性支持lambda表达式,能让代码看起来更简洁。
interface Aaa{
public void printz(String z);
}
//老版本
String t="gggg";
Aaa olda=new Aaa() {
@Override
public void printz(String z) {
// TODO Auto-generated method stub
System.out.println(z);
}
};
olda.printz(t);
//JAVA 8
//变量t在只后不得更改值,否则会报错,Local variable t defined in an enclosing
//scope must be final or effectively final
//lambda表达式内部只能调用final修饰的变量
Aaa zAaa=((String z)->System.out.println(z+"qq"+t));
zAaa.printz(t);
//老版本
Runnable oldrunnable=new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
System.out.println("helloWorld");
}
};
new Thread(oldrunnable).start();
//java 8
new Thread(()->System.out.print("helloWorld8")).start();
结果
List<Name> names = new ArrayList<Name>();
names.add(new Name("Bob"));
names.add(new Name("JECK"));
names.add(new Name("AICE"));
names.add(new Name("SENCE"));
names.add(new Name("MONTE"));
names.forEach(Name::printz);
}
class Name{
private String name;
public Name(String name) {
this.name=name;
}
public void printz() {
System.out.println(name);
}
}`
输出
Bob
JECK
AICE
SENCE
MONTE
java8新提供了很多函数式接口,具体自行搜索,这里用其中一种做例子。
public static void method1(List<Integer> list,Predicate<Integer> predicate) {
for (Integer integer : list) {
if(predicate.test(integer)) {
System.out.print(integer+" ");
}
}
}
List<Integer> nIntegers=Arrays.asList(1,2,3,4,5,6,7,8,9,10);
//如何获取list里大于5的元素呢?
//老方法
for (Integer integer : nIntegers) {
if(integer>5) {
System.out.print(integer+" ");
}
}
System.out.println();
//运用java8提供的函数接口
method1(nIntegers, n->n>5);
System.out.println();
//运用java8新特性省略方法,更简洁
nIntegers.stream().filter(n->n>5).forEach(System.out::print);
结果
Java 8 新增了接口的默认方法。
简单说,默认方法就是接口可以有实现方法,而且不需要实现类去实现其方法。
我们只需在方法名前面加个default关键字即可实现默认方法
为了解决接口的修改与现有的实现不兼容的问题。
public class Java8Test {
@Test
public void test() {
System.out.println(new SimpleDateFormat("yyyy-MM-dd").format(new Date()));
CarS car=new CarS();
car.ss();
}
public interface Car{
default void haha() {
System.out.println("haha");
}
}
public interface Bus{
default void haha() {
System.out.println("heihei");
}
}
public class CarS implements Car,Bus{
public void ss() {
haha();
}
@Override
public void haha() {
// TODO Auto-generated method stub
Bus.super.haha();
Car.super.haha();
}
}
}
java8引入一种新的抽象称做流Stream,能以声明的方式来处理数据。
下面代码实现了随机产生10个数,并把大于0的数输出。
Random random=new Random();
random.ints().limit(10).filter(n->n>0).forEach(System.out::println);
下面代码对list里的字符串重复拼接输出到5条记录的数组里,并输出数组。
List<String> sList=Arrays.asList("a","b","c","d","e","f","g");
System.out.println(sList.stream().map(n->n+n).limit(5).collect(Collectors.toList()));
另外,parallelStream()相对于stream(),是流并行处理方式。
统计结果的收集器
List<Integer> numbers = Arrays.asList(3, 2, 2, 3, 7, 3, 5);
IntSummaryStatistics stats = numbers.stream().mapToInt((x) -> x).summaryStatistics();
System.out.println("列表中最大的数 : " + stats.getMax());
System.out.println("列表中最小的数 : " + stats.getMin());
System.out.println("所有数之和 : " + stats.getSum());
System.out.println("平均数 : " + stats.getAverage());
一个可以存放null的容器,解决了nullpoint空指针问题。
Integer value1 = null;
Integer value2 = 222;
Optional<Integer> a = Optional.ofNullable(value1);
// Optional.of - 如果传递的参数是 null,抛出异常 NullPointerException
Optional<Integer> b = Optional.of(value2);
System.out.println(a.orElse(555));
System.out.println(b.get());
输出555
222
其中a.orElse为如果为空值则取555,b若为空则抛出异常。
Nashorn 一个 javascript 引擎。
从JDK 1.8开始,Nashorn取代Rhino(JDK 1.6, JDK1.7)成为Java的嵌入式JavaScript引擎。Nashorn完全支持ECMAScript 5.1规范以及一些扩展。它使用基于JSR 292的新语言特性,其中包含在JDK 7中引入的 invokedynamic,将JavaScript编译成Java字节码。
与先前的Rhino实现相比,这带来了2到10倍的性能提升。
实现了java和JavaScript互相调用。
ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
ScriptEngine nashorn = scriptEngineManager.getEngineByName("nashorn");
String name = "Runoob"; Integer result = null;
try {
nashorn.eval("print('" + name + "')");
result = (Integer)
nashorn.eval("10 + 2");
}catch(ScriptException e){
System.out.println("执行脚本错误: "+ e.getMessage());
}
System.out.println(result.toString());
输出Runoob 12
var BigDecimal = Java.type('java.math.BigDecimal');
function calculate(amount, percentage) {
var result = new BigDecimal(amount).multiply( new BigDecimal(percentage)).divide(new BigDecimal("100"), 2, BigDecimal.ROUND_HALF_EVEN);
return result.toPlainString(); }
var result = calculate(568000000000000000023,13.9);
print(result);
命令行运行上诉程序 : jjs xxx.js
结果:78952000000000002017.94
旧版java中,日期时间相关的类存在诸多问题:非线程安全、设计差(java.util和java.sql中日期类名相同,但对应内容不一致,前者多了具体时间)、时区处理麻烦。
java8在java.time包里引入了很多新的API:local、 zoned….
// 获取当前的日期时间
LocalDateTime currentTime = LocalDateTime.now();
System.out.println("LocalDateTime.now: " + currentTime);
LocalDate date1 = currentTime.toLocalDate();
System.out.println("localdatetime.tolocaldate=localdate: " + date1);
Month month = currentTime.getMonth();
int day = currentTime.getDayOfMonth();
int seconds = currentTime.getSecond();
System.out.println("localdatetime.getmonth=month: " + month +", localdatetime.getdayofmonth=int: " + day +", localdatetime.getseconds=int: " + seconds);
//用当前时间,修改天数和年份
LocalDateTime date2 = currentTime.withDayOfMonth(10).withYear(2012);
System.out.println("date2: " + date2);
//设置一个日期对象的值
LocalDate date3 = LocalDate.of(2014, Month.DECEMBER, 12);
System.out.println("date3: " + date3);
//设置时间的值
LocalTime date4 = LocalTime.of(22, 15);
System.out.println("date4: " + date4);
//用另一种格式设置时间
LocalTime date5 = LocalTime.parse("20:15:30");
System.out.println("date5: " + date5);
输出:LocalDateTime.now: 2018-10-13T20:14:29.390
localdatetime.tolocaldate=localdate: 2018-10-13
localdatetime.getmonth=month: OCTOBER, localdatetime.getdayofmonth=int: 13, localdatetime.getseconds=int: 29
date2: 2012-10-10T20:14:29.390
date3: 2014-12-12
date4: 22:15
date5: 20:15:30
时区相关:
ZonedDateTime date1 = ZonedDateTime.parse("2015-12-03T10:15:30+05:30[Asia/Shanghai]");
System.out.println("date1: " + date1);
ZoneId id = ZoneId.of("Europe/Paris");
System.out.println("ZoneId: " + id);
ZoneId currentZone = ZoneId.systemDefault();
System.out.println("当期时区: " + currentZone);
ZonedDateTime dateTime=ZonedDateTime.now(currentZone);
System.out.println("当前时区时间:"+dateTime);
输出:
date1: 2015-12-03T10:15:30+08:00[Asia/Shanghai]
ZoneId: Europe/Paris
当期时区: Asia/Shanghai
当前时区时间:2018-10-13T20:20:45.466+08:00[Asia/Shanghai]
时间相关的计算:计算上个月的今天是周几?
LocalDateTime currentTime = LocalDateTime.now();
currentTime=currentTime.withMonth(currentTime.getMonthValue()-1);
System.out.println(currentTime.getDayOfWeek());
结果:THURSDAY
Java 8 内置了 Base64 编码的编码器和解码器。
try {
// 使用基本编码
String base64encodedString = Base64.getEncoder().encodeToString("runoob?java8".getBytes("utf-8"));
System.out.println("Base64 比那么字符串 (基本) :" + base64encodedString);
// 解码
byte[] base64decodedBytes = Base64.getDecoder().decode(base64encodedString);
System.out.println("原始字符串: " + new String(base64decodedBytes, "utf-8"));
base64encodedString = Base64.getUrlEncoder().encodeToString("TutorialsPoint?java8".getBytes("utf-8"));
System.out.println("Base64 编码字符串 (URL) :" + base64encodedString);
StringBuilder stringBuilder = new StringBuilder();
for (int i = 0; i < 10; ++i) {
stringBuilder.append(UUID.randomUUID().toString());
}
byte[] mimeBytes = stringBuilder.toString().getBytes("utf-8");
String mimeEncodedString = Base64.getMimeEncoder().encodeToString(mimeBytes);
System.out.println("Base64 编码字符串 (MIME) :" + mimeEncodedString);
byte[] aString=Base64.getMimeDecoder().decode(mimeEncodedString);
String aString2=new String(aString,"utf-8");
System.out.println(aString2);
}catch(UnsupportedEncodingException e){
System.out.println("Error :" + e.getMessage());
}
结果:
Base64 比那么字符串 (基本) :cnVub29iP2phdmE4
原始字符串: runoob?java8
Base64 编码字符串 (URL) :VHV0b3JpYWxzUG9pbnQ_amF2YTg=
Base64 编码字符串 (MIME) :ZDEzM2E2MGEtNTllMS00ZGI5LWE5OWItNDFkNWMwZWU4ZWRlNzVkMmM5NTctMjFmNi00NTM3LWE2
NjQtMTUwNmJkOGU0ZWZjNDk0YjEyMTctM2RhZi00NDQ0LTgzNGItYzE0ZWFiY2ZhZWUxYzUxYjNj
N2MtMjQ0My00Y2UwLTlhZWItNjE0M2EzZDUzNmQ5OGNjMTgxZTgtMjg3MS00ZDY0LTg0MDktZTgw
MGE2OTNlZDdiM2QyOTBiNmQtYTUyYi00NzY3LWFjZmYtMWM0ODRiOGNmNGQzZjhkZjQ0MDItOWMw
Ni00YjMzLWEyZGUtZDcxYzc4N2NiZjBkMzQ2ZTY1OWQtMjU1OS00ZDVjLWE3ZjktMDQyMWNmYmY4
MjVlMmNhMDhkZGItMDU5OC00Yjk1LTg2ZjktNTdmYWRjZDBjMDBiOWYyYmMzYWMtZDAwNi00ZThk
LTlhNjQtNTU3OTcxODk1NjZi
d133a60a-59e1-4db9-a99b-41d5c0ee8ede75d2c957-21f6-4537-a664-1506bd8e4efc494b1217-3daf-4444-834b-c14eabcfaee1c51b3c7c-2443-4ce0-9aeb-6143a3d536d98cc181e8-2871-4d64-8409-e800a693ed7b3d290b6d-a52b-4767-acff-1c484b8cf4d3f8df4402-9c06-4b33-a2de-d71c787cbf0d346e659d-2559-4d5c-a7f9-0421cfbf825e2ca08ddb-0598-4b95-86f9-57fadcd0c00b9f2bc3ac-d006-4e8d-9a64-55797189566b
Over~