Java8新特性

一.List的stream()

 

可以把Stream当成一个高级版本的Iterator。原始版本的Iterator,用户只能一个一个的遍历元素并对其执行某些操作;高级版本的Stream,用户只要给出需要对其包含的元素执行什么操作,比如“过滤掉长度大于10的字符串”、“获取每个字符串的首字母”等,具体这些操作如何应用到每个元素上,就给Stream就好了!

Java8新特性_第1张图片

 

Stream语法详解:http://ifeve.com/stream/

 

lambda表达式

lambda:一段带有输入参数的可执行语句块

lambda表达式的一般语法:

(Type1 param1, Type2 param2, ..., TypeN paramN) -> {

      statment1;

      statment2;

     //.............

      return statmentM;

    }

 

 

参数类型省略–绝大多数情况,编译器都可以从上下文环境中推断出lambda表达式的参数类型。这样lambda表达式就变成了:

(param1,param2, ..., paramN) -> {

  statment1;

  statment2;

  //.............

  return statmentM;

}

当lambda表达式的参数个数只有一个,可以省略小括号。lambda表达式简写为

param1 -> {

  statment1;

  statment2;

  //.............

  return statmentM;

}

 

当lambda表达式只包含一条语句时,可以省略大括号、return和语句结尾的分号。lambda表达式简化为:

param1 -> statment

 

lambda表达式语法:http://ifeve.com/lambda/

 

 

 

Collectors

List.stream().collect(Collectors的一系列方法)

 

CollectorstoMap

将list转为map

1.常用方式

代码如下:

public Map getIdNameMap(List accounts) {
    return accounts.stream().collect(
            Collectors.toMap(Account::getId, Account::getUsername)
    );
}

 

 

2.收集成实体本身map

代码如下:

 

public Map getIdAccountMap(List accounts) {
    return accounts.stream().collect(
            Collectors.toMap(Account::getId, account -> account)
    );
}

 

 

account -> account是一个返回本身的lambda表达式,其实还可以使用Function接口中的一个默认方法代替,使整个方法更简洁优雅:

 

public Map getIdAccountMap(List accounts) {
    return accounts.stream().collect(
            Collectors.toMap(Account::getId, Function.identity())
    );
}

 

 

3.重复key的情况

代码如下:

public Map getNameAccountMap(List accounts) {
    return accounts.stream().collect(
            Collectors.toMap(Account::getUsername, Function.identity())
    );
}

 

 

这个方法可能报错(java.lang.IllegalStateException: Duplicate key),因为name是有可能重复的。toMap有个重载方法,可以传入一个合并的函数来解决key冲突问题:

 

public Map getNameAccountMap(List accounts) {
    return accounts.stream().collect(
            Collectors.toMap(
                    Account::getUsername, Function.identity(), (key1, key2) -> key2
            )
    );
}

 

 

这里只是简单的使用后者覆盖前者来解决key重复问题。

4.指定具体收集的map

toMap还有另一个重载方法,可以指定一个Map的具体实现,来收集数据:

 

public Map getNameAccountMap(List accounts){
    return accounts.stream().collect(
            Collectors.toMap(
                    Account::getUsername, Function.identity(), (key1, key2) ->
                            key2,LinkedHashMap::new)
    );
}

 

 

参考:https://zacard.net/2016/03/17/java8-list-to-map/

 

CollectorsgroupingBy

展示如何使用Java 8 Stream Collectors进行分组,计数,总和和排序List

 

 

1.分组,计数和排序

 

1.1分组List并显示其总数。

Java8Example1.java

 

package com.mkyong.java8;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
    public class Java8Example1 {
        public static void main(String[] args) {
            //3 apple, 2 banana, others 1
            List items =
                    Arrays.asList("apple", "apple", "banana",
                            "apple", "orange", "banana", "papaya");
            Map result =
                    items.stream().collect(
                            Collectors.groupingBy(
                                    Function.identity(), Collectors.counting()
                            )
                    );
            System.out.println(result);
        }
    }

 

 

Output

 

    {papaya=1, orange=1, banana=2, apple=3}
//中文翻译
    {番木瓜= 1,橙= 1,香蕉= 2,苹果= 3}

 

 

1.2添加排序。

Java8Example2.java

package com.mkyong.java8;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
    public class Java8Example2 {
        public static void main(String[] args) {
            //3 apple, 2 banana, others 1
            List items =
                    Arrays.asList("apple", "apple", "banana",
                            "apple", "orange", "banana", "papaya");
            Map result =
                    items.stream().collect(
                            Collectors.groupingBy(
                                    Function.identity(), Collectors.counting()
                            )
                    );
            Map finalMap = new LinkedHashMap<>();
            //Sort a map and add to finalMap
            result.entrySet().stream()
                    .sorted(Map.Entry.comparingByValue()
                            .reversed()).forEachOrdered(e -> finalMap.put(e.getKey(), e.getValue()));
            System.out.println(finalMap);
        }
    }

 

Output

 

{
    苹果= 3,香蕉= 2,木瓜= 1,橙= 1
}

 

 

 

2.List Objects

“分组”用户定义的对象列表的示例。

 

2.1 Pojo

 

Item.java

 

package com.mkyong.java8;
import java.math.BigDecimal;
    public class Item {
        private String name;
        private int qty;
        private BigDecimal price;
        //constructors, getter/setters
    }

 

 

 

2.2 按姓名+数字或数量组合。

Java8Examples3.java

 

package com.mkyong.java8;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
    public class Java8Examples3 {
        public static void main(String[] args) {
            //3 apple, 2 banana, others 1
            List items = Arrays.asList(
                    new Item("apple", 10, new BigDecimal("9.99")),
                    new Item("banana", 20, new BigDecimal("19.99")),
                    new Item("orang", 10, new BigDecimal("29.99")),
                    new Item("watermelon", 10, new BigDecimal("29.99")),
                    new Item("papaya", 20, new BigDecimal("9.99")),
                    new Item("apple", 10, new BigDecimal("9.99")),
                    new Item("banana", 10, new BigDecimal("19.99")),
                    new Item("apple", 20, new BigDecimal("9.99"))
            );
            Map counting = items.stream().collect(
                    Collectors.groupingBy(Item::getName, Collectors.counting()));
            System.out.println(counting);
            Map sum = items.stream().collect(
                    Collectors.groupingBy(Item::getName, Collectors.summingInt(Item::getQty)));
            System.out.println(sum);
        }
    }

 

Output

 

// Group by + Count
    {
        番木瓜= 1,香蕉= 2,苹果= 3,猩猩= 1,西瓜= 1
    }
    // Group by + Sum qty
    {
        番木瓜= 20,香蕉= 30,苹果= 40,orang = 10,西瓜= 10
    }

 

 

2.3按价格分组

-Collectors.groupingBy以Collectors.mapping示例为例。

 

Java8Examples4.java

 

package com.mkyong.java8;
import java.math.BigDecimal;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
    public class Java8Examples4 {
        public static void main(String[] args) {
            //3 apple, 2 banana, others 1
            List items = Arrays.asList(
                    new Item("apple", 10, new BigDecimal("9.99")),
                    new Item("banana", 20, new BigDecimal("19.99")),
                    new Item("orang", 10, new BigDecimal("29.99")),
                    new Item("watermelon", 10, new BigDecimal("29.99")),
                    new Item("papaya", 20, new BigDecimal("9.99")),
                    new Item("apple", 10, new BigDecimal("9.99")),
                    new Item("banana", 10, new BigDecimal("19.99")),
                    new Item("apple", 20, new BigDecimal("9.99"))
            );
            //group by price
            Map> groupByPriceMap =
                    items.stream().collect(Collectors.groupingBy(Item::getPrice));
            System.out.println(groupByPriceMap);
            // group by price, uses 'mapping' to convert List to Set
            Map> result =
                    items.stream().collect(
                            Collectors.groupingBy(Item::getPrice,
                                    Collectors.mapping(Item::getName, Collectors.toSet())
                            )
                    );
            System.out.println(result);
        }
    }

 

 

 

Output

    {
        19.99 = [
        Item {name ='banana',qty = 20,price = 19.99},
        Item {name ='banana',qty = 10,price = 19.99}
      ]
        29.99 = [
        Item {name ='orang',qty = 10,price = 29.99},
        Item {name ='watermelon',qty = 10,price = 29.99}
      ]
        9.99 = [
        Item {name ='apple',qty = 10,price = 9.99},
        Item {name ='papaya',qty = 20,price = 9.99},
        Item {name ='apple',qty = 10,price = 9.99},
        Item {name ='apple',qty = 20,price = 9.99}
      ]
    }

// group by +映射到Set
    {
        19.99 = [香蕉]
        29.99 = [orang,西瓜],
        9.99 = [番木瓜,苹果]
    }

 

 

参考:https://blog.csdn.net/Hatsune_Miku_/article/details/73414406

 

 

 

 

 

 

 

三.LocalDateTime

LocalTime :  只包括时间

LocalDate : 只包括日期

LocalDateTime : 包括日期和时间

 

以下测试代码

简直好用到爆

public class TimeTest {
 
  @Test
  public void testTime() {
 LocalDateTime time = LocalDateTime.now();
 
 System.out.println(time.toString()); //字符串表示
 System.out.println(time.toLocalTime()); //获取时间(LocalTime)
 System.out.println(time.toLocalDate()); //获取日期(LocalDate)
 System.out.println(time.getDayOfMonth()); //获取当前时间月份的第几天
 System.out.println(time.getDayOfWeek());  //获取当前周的第几天
 System.out.println(time.getDayOfYear());  //获取当前时间在该年属于第几天
 System.out.println(time.getHour());
 System.out.println(time.getMinute());
 System.out.println(time.getMonthValue());
 System.out.println(time.getMonth());
 System.out.println("-----------------------------------");
 //格式化输出
 DateTimeFormatter formatter = DateTimeFormatter.ofPattern("YYYY/MM/dd HH:mm:ss");
 System.out.println(time.format(formatter));
 //构造时间
 LocalDateTime startTime = LocalDateTime.of(2018, 1, 1, 20, 31, 20);
 LocalDateTime endTime = LocalDateTime.of(2018, 1, 3, 20, 31, 20);
 //比较时间
 System.out.println(time.isAfter(startTime));
 System.out.println(time.isBefore(endTime));
 
 //时间运算,相加相减
 System.out.println(time.plusYears(2)); //加2年
 System.out.println(time.plusDays(2)); //加两天
 System.out.println(time.minusYears(2)); //减两年
 System.out.println(time.minusDays(2)); //减两天
 
 //获取毫秒数(使用Instant)
 System.out.println(time.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli());
//获取秒数(使用Instant)
 System.out.println(time.atZone(ZoneId.systemDefault()).toInstant().getEpochSecond());
    }
 
    }

 

 

参考:https://www.cnblogs.com/wt20/p/8179118.html

 

 

你可能感兴趣的:(Java8新特性)