Java 8 特性
Lambda 表达式
Java 8 引入的Lambda表达式是Java语言的一个重大革新,它极大地增强了Java对于函数式编程的支持。
Lambda表达式的引入使得代码更为简洁,函数式接口实现等方面带来了极大的便利。
Lambda语法
// 实现方法
(parameters) -> expression
或
(parameters) ->{ statements; }
// 传递方法或者构造函数引用(比如打印)
System.out::println
Lambda使用案例
替代匿名内部类
// 以前
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("The runable now is using!");
}
}).start();
//用lambda
new Thread(() -> System.out.println("It's a lambda function!")).start();
迭代集合
List<String> strings = Arrays.asList("1", "2", "3");
// 以前
for (String s : strings) {
System.out.println(s);
}
//Lambda foreach
strings.forEach((s) -> System.out.println(s));
//or
strings.forEach(System.out::println);
//map
Map<Integer, String> map = new HashMap<>();
map.forEach((k,v)->System.out.println(v));
访问变量
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int i = 1;
// 可以访问外边变量i,但注意,外边变量在lambda中默认拥有final属性
// 不可以修改,如果修改,编译报错
numbers.forEach(n -> System.out.println(n - i));
Java Steam
Java 8 新增了java.util.stream包,它可以对集合数据进行排序,筛选,过滤等处理方式。
在代码中,一定程度上替代了以前对集合的for循环,让代码更加干净,简洁,高效。
它的源数据可以是 Collection、Array 等。由于它的方法参数都是函数式接口类型,所以一般和 Lambda 配合使用。
Steam语法
// steam的操作有三个步骤
// 1.创建Stream
// 2.中间操作:对数据进行处理
// 3.终止操作:一旦执行终止操作 ,就执行了中间操作链,并产生结果,之后就不会再被使用。这也是为什么说Stream是延迟执行的原因。
// 实际使用中常常将三个步骤合并一起执行
// 下面演示分开执行的步骤
// 创建数据源
List<String> strings = Arrays.asList("a", "b", "c", "d", "e");
// 步骤1:创建steam流
// 创建串行流
Stream<String> stream = strings.stream();
// 创建并行流(多线程执行,不常用)
Stream<String> parallelStream = strings.parallelStream()
// 数组创建(串行流)
String [] s = {"a" ,"b"};
Stream<String> stream= Arrays.stream(s);
// 还有其他创建流方法入Steam.of() 这里不再介绍
// 步骤2:中间操作
//中间操作符:
// 通过filter方法对集合中每个元素进行过滤
//filter
// 通过map方法对集合中每个元素进行操作
//map
// 排序
//sort
// 限制流,例如只取前流的前几个元素
//limit
// 跳过操作,例如跳过流的前几个元素
//skip
// 统计个数
//count
// 下面通过filter对集合进行过滤,过滤条件为 equals(a)
Stream<String> stringa = stream.filter(s -> s.equals("a"));
// 步骤3:终止符操作
// 终止操作符:
//收集操作,将所有数据收集起来,Stream 的核心在于Collectors,常用的Collectors.toSet()、Collectors.toList()、Collectors.groupingBy()。
//collect
//统计操作,统计最终的数据个数。
//count
//查找操作,查找第一个、查找任何一个 返回的类型为Optional。
//findFirst、findAny
//匹配操作,数据流中是否存在符合条件的元素 返回值为bool 值。
//noneMatch、allMatch、anyMatch
//最值操作,需要自定义比较器,返回数据流中最大最小的值。
//min、max
//规约操作,将整个数据流的值规约为一个值,count、min、max底层就是使用reduce。
//reduce
//遍历操作,这里就是对最终的数据进行消费了。
//forEach、forEachOrdered
//数组操作,将数据流的元素转换成数组。
//toArray
// 将中间操作之后的结果数据通过collect收集起来
// 通过Collectors.toList() 转换为一个List集合
List<String> collect = stringa.collect(Collectors.toList());
Steam使用案例
实际使用中常常会把stream的三个步骤合并在一起使用,这样使代码更加简洁。
// 数据源1:字符串集合
List<String> strings = Arrays.asList("a", "b", "c", "d", "e");
// 数据源2:LoginUser为用户信息对象
List<LoginUser> list = ...
// 过滤:找到不等于a的元素
List<String> collect = strings.stream().filter(item -> !"a".equals(item))
.collect(Collectors.toList());
// map:获取用户集合的全部用户名
List<String> usernames = list.stream().map(LoginUser::getUsername)
.collect(Collectors.toList());
// sort 排序:根据用户ID进行排序
//升序 默认
List<LoginUser> collect1 = list.stream().sorted(Comparator.comparing(LoginUser::getUserid))
.collect(Collectors.toList());
// 降序 reversed()
List<LoginUser> collect2 = list.stream().sorted(Comparator.comparing(LoginUser::getUserid).reversed())
.collect(Collectors.toList());
// sort排序:多字段排序 根据用户ID升序,登入时间降序
list.stream().sorted(Comparator.comparing(LoginUser::getUserid)
.thenComparing(LoginUser::getLoginTime).reversed()
)
.collect(Collectors.toList());
// limit 取前三个元素
List<String> collect3 = strings.stream().limit(3)
.collect(Collectors.toList());
// skip 跳过前三个元素
List<String> collect4 = strings.stream().skip(3)
.collect(Collectors.toList());
// count 计算数量
long count1 = strings.stream().filter(item -> !"a".equals(item)).count();
Date-Time
这是对java.util.Date强有力的补充,解决了 Date 类的大部分痛点:
非线程安全
时区处理麻烦
各种格式化、和时间计算繁琐
设计有缺陷,Date 类同时包含日期和时间
java.time 主要类
LocalDateTime.class //日期+时间 format: yyyy-MM-ddTHH:mm:ss.SSS
LocalDate.class //日期 format: yyyy-MM-dd
LocalTime.class //时间 format: HH:mm:ss
格式化
// Date
Date now = new Date();
//format yyyy-MM-dd
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String date = sdf.format(now);
//format HH:mm:ss
SimpleDateFormat sdft = new SimpleDateFormat("HH:mm:ss");
String time = sdft.format(now);
//format yyyy-MM-dd HH:mm:ss
SimpleDateFormat sdfdt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String datetime = sdfdt.format(now);
//---------------------------------------------------------------------------------
// Date Time
//format yyyy-MM-dd
LocalDate date = LocalDate.now();
//format HH:mm:ss
LocalTime time = LocalTime.now().withNano(0);
//format yyyy-MM-dd HH:mm:ss
LocalDateTime dateTime = LocalDateTime.now();
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String dateTimeStr = dateTime.format(dateTimeFormatter);
字符串日期转化
// Date
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date1 = sdf.parse("2021-01-26");
//---------------------------------------------------------------------------------
// Date Time
LocalDate date = LocalDate.of(2024, 3, 1);
LocalDate date = LocalDate.parse("2024-03-01");
LocalTime time = LocalTime.of(8, 20, 20);
LocalTime time = LocalTime.parse("08:20:20");
LocalDateTime dateTime = LocalDateTime.of(2024, 3, 1, 8, 20, 20);
LocalDateTime dateTime = LocalDateTime.parse("2024-03-01 08:20:20");
日期计算
// Date
//一周后的日期
SimpleDateFormat formatDate = new SimpleDateFormat("yyyy-MM-dd");
Calendar ca = Calendar.getInstance();
ca.add(Calendar.DATE, 7);
Date d = ca.getTime();
String after = formatDate.format(d);
System.out.println("一周后日期:" + after);
//算两个日期间隔多少天,计算间隔多少年,多少月方法类似
String dates1 = "2021-12-23";
String dates2 = "2021-02-26";
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
Date date1 = format.parse(dates1);
Date date2 = format.parse(dates2);
int day = (int) ((date1.getTime() - date2.getTime()) / (1000 * 3600 * 24));
System.out.println(dates1 + "和" + dates2 + "相差" + day + "天");
//结果:2021-02-26和2021-12-23相差300天
//---------------------------------------------------------------------------------
// Date Time
//一周后的日期
LocalDate localDate = LocalDate.now();
//方法1
LocalDate after = localDate.plus(1, ChronoUnit.WEEKS);
//方法2
LocalDate after2 = localDate.plusWeeks(1);
System.out.println("一周后日期:" + after);
//算两个日期间隔多少天,计算间隔多少年,多少月
LocalDate date1 = LocalDate.parse("2021-02-26");
LocalDate date2 = LocalDate.parse("2021-12-23");
Period period = Period.between(date1, date2);
System.out.println("date1 到 date2 相隔:"
+ period.getYears() + "年"
+ period.getMonths() + "月"
+ period.getDays() + "天");
//打印结果是 “date1 到 date2 相隔:0年9月27天”
//这里period.getDays()得到的天是抛去年月以外的天数,并不是总天数
//如果要获取纯粹的总天数应该用下面的方法
long day = date2.toEpochDay() - date1.toEpochDay();
System.out.println(date1 + "和" + date2 + "相差" + day + "天");
//打印结果:2021-02-26和2021-12-23相差300天
获取指定日期
// Date
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
//获取当前月第一天:
Calendar c = Calendar.getInstance();
c.set(Calendar.DAY_OF_MONTH, 1);
String first = format.format(c.getTime());
System.out.println("first day:" + first);
//获取当前月最后一天
Calendar ca = Calendar.getInstance();
ca.set(Calendar.DAY_OF_MONTH, ca.getActualMaximum(Calendar.DAY_OF_MONTH));
String last = format.format(ca.getTime());
System.out.println("last day:" + last);
//当年最后一天
Calendar currCal = Calendar.getInstance();
Calendar calendar = Calendar.getInstance();
calendar.clear();
calendar.set(Calendar.YEAR, currCal.get(Calendar.YEAR));
calendar.roll(Calendar.DAY_OF_YEAR, -1);
Date time = calendar.getTime();
System.out.println("last day:" + format.format(time));
//---------------------------------------------------------------------------------
// Date Time
LocalDate today = LocalDate.now();
//获取当前月第一天:
LocalDate firstDayOfThisMonth = today.with(TemporalAdjusters.firstDayOfMonth());
// 取本月最后一天
LocalDate lastDayOfThisMonth = today.with(TemporalAdjusters.lastDayOfMonth());
//取下一天:
LocalDate nextDay = lastDayOfThisMonth.plusDays(1);
//当年最后一天
LocalDate lastday = today.with(TemporalAdjusters.lastDayOfYear());
//2021年最后一个周日,如果用Calendar是不得烦死。
LocalDate lastMondayOf2021 = LocalDate.parse("2021-12-31").with(TemporalAdjusters.lastInMonth(DayOfWeek.SUNDAY));
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 七十七
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果