文档章节

Java 8 新增内容介绍

landyking
 landyking
发布于 2018/12/11 17:37
字数 1154
阅读 1
收藏 0

大纲

  1. Lambda 表达式
  2. FP(函数式编程)
  3. 日期和时间库
  4. 杂项

Lambda 表达式

Lambda 表达式说明

  1. Lambda 表达式是一个带有参数的代码块。
  2. Lambda 表达式是一段可以传递的代码。
  3. Lambda 表达式可以被转换为函数式接口。
  4. Lambda 表达式可以在闭包作用域中有效的访问final变量。

Java Lambda 示例

定义一个lambda

Predicate<String> notNull1 = (s) -> {
    return Objects.nonNull(s);
};

Predicate<String> notNull2= s -> Objects.nonNull(s);

Method Reference(方法引用)

Predicate<String> notNull3= Objects::nonNull;

直接传递lambda表达式

new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("new thread run !");
    }
}).start();

new Thread(()-> System.out.println("new thread run !")).start();

函数式接口指的是拥有@FunctionalInterface注解的接口。

package java.lang;

@FunctionalInterface
public interface Runnable {
    public abstract void run();
}

变量作用域

int outer = 0;

@Test
public void testVar() throws Exception {
    int local = 0;//隐式为final
    int old=outer;
    Runnable run = () -> {
        System.out.println(local);//可以调用
        System.out.println(outer);//可以调用
        //local++; 编译错误,无法改变local的值
        outer++;//可以更改
    };
    run.run();
    Assert.assertEquals(old + 1, outer); //通过
}

反向排序

List<Integer> list = Arrays.asList(10, 20, 1, 22, 33);
Collections.sort(list, (o1, o2) -> Integer.compare(o2, o1));

延迟执行

logger.info("x: "+x+", y: "+y+", student: "+student.toString());

logger.info(()->"x: "+x+", y: "+y+", student: "+student.toString());

方法引用用于sql查询

sqlManager.lambdaQuery(Device.class)
	.andEq(Device::getDevNo, devno)
	.andEq(Device::getDeleteFlag, AppConst.YesOrNo.no)
	.single();

FP(函数式编程)

stream 相关API

  • 新增包java.uti.stream
  • java.util.Collectionjava.util.Map等接口增加相关方法。
  • 一些通用的FunctionalInterface(函数式接口)。下面列出只是部分。
    • java.util.function.Supplier
    • java.util.function.Function
    • java.util.function.BiFunction
    • java.util.function.Predicate
    • java.util.function.BiPredicate
    • java.util.function.Consumer
    • java.util.function.BiConsumer

接口默认方法

Java8 在原有的Collection和Map等接口中增加了新的方法。会导致对旧程序不兼容。 比如你写了一个QuickMap,实现了旧的Map接口。Java8在Map接口中增加了新方法,但QuickMap并没有实现它们。

为了向前兼容,Java8在语言层面增肌了新特性,那就是接口默认方法。 针对我们刚才举例的情况,Java8是这么解决的,代码如下:

package java.util;
public interface Map<K,V> {
	
    default V getOrDefault(Object key, V defaultValue) {
        V v;
        return (((v = get(key)) != null) || containsKey(key))
            ? v
            : defaultValue;
    }

    default void forEach(BiConsumer<? super K, ? super V> action) {
        Objects.requireNonNull(action);
        for (Map.Entry<K, V> entry : entrySet()) {
            K k;
            V v;
            try {
                k = entry.getKey();
                v = entry.getValue();
            } catch(IllegalStateException ise) {
                // this usually means the entry is no longer in the map.
                throw new ConcurrentModificationException(ise);
            }
            action.accept(k, v);
        }
    }

    ......
}

Stream 关键方法

  • filter 过滤
  • map 转换
  • flatMap 展开并转换
  • collect 收集stream中的数据
  • reduce 聚合操作

Stream 示例代码

取字符串列表中,不为空的,小写的,每个字符串的开头和末尾两个字符,组成新的列表。

List<String> wordList = Arrays.asList("Hello","", "WOrld", "Lily", "and"," ", "Han");
List<Character> charList = wordList.stream()
        .filter(w -> w != null && w.trim().length() >= 2)
        .map(w -> w.toLowerCase())  // .map(String::toLowerCase);
        .flatMap(w -> Stream.of(w.charAt(0), w.charAt(w.length() - 1)))
        .collect(Collectors.toList());

通过账号列表获取逗号分隔的id列表

List<Account> accountList = ... ;
String ids = accountList.stream()
	.map(Account::getId)
	.collect(Collectors.joining(","));

通过账号列表,获取id到username的映射

Map<String, String> idToName = accountList.stream()
	.collect(Collectors.toMap(Account::getId, Account::getUsername));

账号按部门分组

List<Account> accountList = ... ;
Map<String, List<Account>> depWithAccountList = accountList.stream()
        .filter(a -> a.getDepId() != null)
        .collect(Collectors.groupingBy(Account::getDepId));

计算和

List<Integer> nums = Arrays.asList(1, 3, 4, 6, 2, 3, 1);

Integer sum = nums.stream().reduce(0, (x, y) -> x + y);

Optional<Integer> sum2 = nums.stream().reduce((x, y) -> x + y);

int sum3 = nums.stream().mapToInt(Integer::intValue).sum();

日期和时间库

java.time

  1. java.time.Instant 时间线上的一个时间点.
  2. java.time.Duration 两个时间点之间间隔.
  3. java.time.LocalDateTime日期时间,与时区无关。
  4. java.time.ZonedDateTime日期时间,与时区关联。

示例代码

获取当前毫秒值

Instant.now().toEpochMilli()

打印当前日期时间

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

LocalDateTime now = LocalDateTime.now();//instant + offset
System.out.println(dateTimeFormatter.format(now));

ZonedDateTime now1 = ZonedDateTime.now();//instant + zone
System.out.println(dateTimeFormatter.format(now1));

Instant|LocalDateTime|ZonedDateTime 之间转换

LocalDateTime localDateTime = LocalDateTime.ofInstant(Instant.now(),
		ZoneId.systemDefault());
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(Instant.now(), 
		ZoneId.systemDefault());

ZonedDateTime zonedDateTimeTmp = LocalDateTime.now().atZone(ZoneId.systemDefault());

Instant instant = zonedDateTimeTmp.toInstant();

与Date的转换

Date from = Date.from(Instant.now());
Instant instant = new Date().toInstant();

杂项

String自带join

String join = String.join(",", "1", "3", "4");
String join1 = String.join(",", Arrays.asList("2", "3", "6"));
String join2 = String.join(",", new String[]{"1", "2", "3"});
System.out.println(join);
System.out.println(join1);
System.out.println(join2);

Optional 可选值

Random r = new Random();
Optional<String> val = Optional.ofNullable(r.nextBoolean() ? null : "1");
//不为空时才处理
val.ifPresent(v -> {
    String line = v + "hello";
    System.out.println(line);
});
//不为空则转换为int,为空则返回-1
Integer number = val.map(Integer::parseInt).orElse(-1);

Optional<Object> empty = Optional.empty();

文件操作 (Java7开始)

按行读取文本文件内容

try(Stream<String> lines= Files.lines(Paths.get("test.txt"))){
    List<String> collect = lines.filter(Texts::hasText)
            .collect(Collectors.toList());
}

遍历目录,包含子目录。深度优先遍历

try (Stream<Path> entries = Files.walk(Paths.get("rootDir"))) {
    //打印文件名
    entries.map(Path::getFileName)
            .peek(System.out::println);
}

java.util.Objects (Java7开始)

  • Objects#equals
  • Objects#deepEquals
  • Objects#hashCode
  • Objects#toString
  • Objects#compare
  • Objects#requireNonNull
  • Objects#isNull
  • Objects#nonNull
  • ......

© 著作权归作者所有

共有 人打赏支持
landyking
粉丝 11
博文 50
码字总数 28330
作品 0
郑州
高级程序员
私信 提问
JVM系列第1讲:Java 语言的前世今生

Java 语言是一门存在了 20 多年的语言,其年纪比我自己还大。虽然存在了这么长时间,但 Java 至今都是最大的工业级语言,许多大型互联网公司均采用 Java 来实现其业务系统。大到国际电商巨头...

陈树义
2018/11/07
0
0
聊聊jesque在redis中的数据结构

序 本文主要介绍一下jesque在redis的存储结构 示例配置 启动时的reids对象 namespace:workers set类型的数据接口,存储该namespace下的workers的名称 namespace:worker:host:queueType,list...

go4it
2017/11/18
0
0
xson 1.0.2 发布,增加 byte[] buffer,支持 XCO

xson 1.0.2 已发布,新版增加了 byte[] buffer,支持 XCO。 新版本特性 新增buffer包,此包中的相关类提供对序列化过程中的byte[]进行分配、使用、回收的管理;进一步提供序列化的速度,并减...

xson_org
2017/07/31
731
0
一起谈谈 Java 9 的新特性

在前一篇博客里,我们探讨了Java 8 新增的功能特性。 Java 8 发布已经三年多了,下一个版本现在已经整装待发了,暂定发布日期是2017年9月21日。 你也许已经听到 Java 9 的模块化系统,不过,...

oschina
2017/07/31
12.6K
42
Java程序员必读书单,家族又添新成员

点击关注异步图书,置顶公众号 每天与你分享IT好书 技术干货 职场知识 参与文末话题讨论,每日赠送异步图书。 ——异步小编 有些革命出其不意地吸引了全世界的眼球。Twitter、Linux操作系统和...

异步社区
2018/05/09
0
0

没有更多内容

加载失败,请刷新页面

加载更多

IOS  学习记录

1.StackView=>IOS 9及以上支持 2.布局方式: AutoLayout / StackView 堆布局 (线性布局) 3.屏幕适配 (资源分辨率、设计分辨率、屏幕分辨率) Size Class技术 可以针对 屏幕的方向进行设置...

萨x姆
44分钟前
3
0
第四次工业革命:自主经济的崛起

https://36kr.com/p/5170370.html

shengjuntu
昨天
3
0
Cloud Native 与12-Factor

12-Factor(twelve-factor),也称为“十二要素”,是一套流行的应用程序开发原则。Cloud Native架构中使用12-Factor作为设计准则。 12-Factor 的目标在于: 使用标准化流程自动配置,从而使...

waylau
昨天
9
0
java多线程2

“非线程安全”问题存在于“实例变量”中,如果是方法内部的私有变量,则不存在线程安全问题。这是因为方法内部的变量都是私有造成的。 synchronized 获取的都是对象锁。如果多个线程访问多个...

一滴水穿石
昨天
4
0
今天的学习

1,document.location.href:获取整个url 2,str.split(' '):用字符分割字符串 3,$this->load->library(' '):引用图像处理类 4,$this->load->library(' '):引用Email类 5,特殊访问指针$th......

墨冥
昨天
6
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部