Java 8 新增内容介绍

大纲

  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
  • ......

转载于:https://my.oschina.net/huanger/blog/2986960

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值