可以把Stream当成一个高级版本的Iterator。原始版本的Iterator,用户只能一个一个的遍历元素并对其执行某些操作;高级版本的Stream,用户只要给出需要对其包含的元素执行什么操作,比如“过滤掉长度大于10的字符串”、“获取每个字符串的首字母”等,具体这些操作如何应用到每个元素上,就给Stream就好了!
Stream语法详解:http://ifeve.com/stream/
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/
List.stream().collect(Collectors的一系列方法)
将list转为map
代码如下:
public Map<Long, String> getIdNameMap(List<Account> accounts) { return accounts.stream().collect( Collectors.toMap(Account::getId, Account::getUsername) );}
代码如下:
public Map<Long, Account> getIdAccountMap(List<Account> accounts) { return accounts.stream().collect( Collectors.toMap(Account::getId, account -> account) );}
account -> account是一个返回本身的lambda表达式,其实还可以使用Function接口中的一个默认方法代替,使整个方法更简洁优雅:
public Map<Long, Account> getIdAccountMap(List<Account> accounts) { return accounts.stream().collect( Collectors.toMap(Account::getId, Function.identity()) );}
代码如下:
public Map<String, Account> getNameAccountMap(List<Account> accounts) { return accounts.stream().collect( Collectors.toMap(Account::getUsername, Function.identity()) );}
这个方法可能报错(java.lang.IllegalStateException: Duplicate key),因为name是有可能重复的。toMap有个重载方法,可以传入一个合并的函数来解决key冲突问题:
public Map<String, Account> getNameAccountMap(List<Account> accounts) { return accounts.stream().collect( Collectors.toMap( Account::getUsername, Function.identity(), (key1, key2) -> key2 ) );}
这里只是简单的使用后者覆盖前者来解决key重复问题。
toMap还有另一个重载方法,可以指定一个Map的具体实现,来收集数据:
public Map<String, Account> getNameAccountMap(List<Account> 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/
展示如何使用Java 8 Stream Collectors进行分组,计数,总和和排序List
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<String> items = Arrays.asList("apple", "apple", "banana", "apple", "orange", "banana", "papaya"); Map<String, Long> 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<String> items = Arrays.asList("apple", "apple", "banana", "apple", "orange", "banana", "papaya"); Map<String, Long> result = items.stream().collect( Collectors.groupingBy( Function.identity(), Collectors.counting() ) ); Map<String, Long> finalMap = new LinkedHashMap<>(); //Sort a map and add to finalMap result.entrySet().stream() .sorted(Map.Entry.<String, Long>comparingByValue() .reversed()).forEachOrdered(e -> finalMap.put(e.getKey(), e.getValue())); System.out.println(finalMap); } }
Output
{ 苹果= 3,香蕉= 2,木瓜= 1,橙= 1}
“分组”用户定义的对象列表的示例。
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<Item> 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<String, Long> counting = items.stream().collect( Collectors.groupingBy(Item::getName, Collectors.counting())); System.out.println(counting); Map<String, Integer> 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<Item> 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<BigDecimal, List<Item>> groupByPriceMap = items.stream().collect(Collectors.groupingBy(Item::getPrice)); System.out.println(groupByPriceMap); // group by price, uses 'mapping' to convert List<Item> to Set<String> Map<BigDecimal, Set<String>> 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
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