JDK8特性

Lambda

1. lambda的基本结构
(param1,param2,param3) -> {body}
	1. 如果参数只有1个,()可以省略
	2. 如果body只有一条语句,{}可以省略
	3. 如果body直接return  可以{}+return一起省略
2. 函数式接口:
	1. 如果一个接口只有1个抽象方法,那么该接口就是一个函数式接口。
	2. 如果在接口上声明@FunctionalInterface注解,那么编译器就会按照函数式接口定义要求该接口。
	3. 如果某个接口只有一个抽象方法,但并没有声明@FunctionalInterface注解,那么编译器依旧会将其看做函数式接口。

example

public class Test1 {
    public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1,2,3,4,5,6);
        list.forEach(i -> System.out.println(i));
        new Thread(()-> System.out.println("123"));
        Collections.sort(list,(o1,o2)->o2.compareTo(o1));
        System.out.println(list);
    }
}

Funcation

1. Funcation接口定义两个泛型,调用apply方法,可以通过第一个参数获取第二个参数
2. example: Funcation<Integer,String> funcation = a -> "hello"+a;
3. 参数或返回值为函数的方法称为高阶函数。
4. Funcation有compose和andThen两种组合函数方法: f1.compose(f2) 先执行f2函数,在执行f1  ,andThen相反
5. BiFuncation可以通过俩参数,得到一个结果,含有andThen方法,将结果拼接其他Funcation
6. BinaryOperator是BiFuncation的一种特殊实现,三个泛型类型一致,用于计算
7. example: BiFuncation<Integer,Integer,Integer> bf = (a,b) -> a+b;
	或者 BiFuncation<Integer,Integer,Integer> bf = (a,b) ->{return a+b;}  调用apply时,即可通过a  b获取计算后的值
8. Predicate<T>,调用test判断结果是否为true
9. example  Predicate<String> predicate = a -> a.length()>3;  System.out.println(predicate.test("aa"));
10. Predicate还存在and和or方法,等效于&&,||   negate 等效于 !
11. Consumer 等于单参无返回值的函数
12. Supplier  不接受参数返回结果 

example

 public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1,2,3,4,5,6,7,8,9,10);
        Predicate<Integer> predicate = a -> a>3;
        list.stream().filter(predicate.and(a->a%2 == 0)).forEach(System.out::println);
    }

Optional

1. Optional没有实现序列化,因此不要作为返回值和参数

语法

public static void main(String[] args) {
        Optional<String> optional = Optional.empty();//建立空对象
        Optional<String> optional2 = Optional.of("aaa"); //建立aaa的Optional对象  of传null时,直接报NPE
        Object obj = null;
        Optional<Object> optional3 = Optional.ofNullable(obj);//不确定是否为null时,使用ofNullable
        System.out.println(optional.isPresent());  //是否存在  empty返回false
        System.out.println(optional2.get());// 返回值  null时报错
        optional2.ifPresent(a -> System.out.println(a));//a为空时不处理
        System.out.println(optional2.orElse("bbb")); // null时打印bbb,否则为本身
        System.out.println(optional2.orElseGet(() -> "hello"));//null时调用Supplier.get
        Student student = new Student();
        student.setBooks(Arrays.asList(new Book()));
        Optional<Student> optionalStudent = Optional.of(student);
        System.out.println(optionalStudent.map(s -> s.getBooks()).orElse(Collections.emptyList()));
        //最终版
        Optional.ofNullable(student).map(a->a.getBooks()).orElse(Collections.emptyList());
    }

Method reference

1. 方法引用实际上是Lambda表达式的一种语法糖  
	a->System.out.println(a);  ==  System.out::println;
2. 方法引用分类:
	1. 类名::静态方法名  参数和返回值和函数一样
	2. 引用名::实例方法名
	3. 类名::实例方法名
	4. 构造方法引用:  类名::new
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Person implements Comparable<Person> {
    private String name;
    private Integer age;

    @Override
    public int compareTo(Person person) {
        return this.getAge() - person.getAge();
    }

    public static int sortAscByAge(Person beforePerson,Person afterPerson){
        return beforePerson.getAge()-afterPerson.getAge();
    }

    private int sortDescByAge(Person beforePerson,Person afterPerson){
        return afterPerson.getAge()-beforePerson.getAge();
    }

    public Person getPerson(Supplier<Person> supplier){
        return supplier.get();
    }
    public String getPerson2(Function<String,String> function){
        return function.apply("aaa");
    }
    public static void main(String[] args) {
        List<Person> list = Arrays.asList(new Person("zs",10),
                new Person("ls",20),
                new Person("ww",15));
        //类名::静态方法名
        list.sort(Person::sortAscByAge);
        //引用名::实例方法名
        Person person = new Person();
        list.sort(person::sortDescByAge);
        //类名::实例方法名
        list.sort(Person::compareTo);
        System.out.println(list);
        //构造方法引用
        System.out.println(person.getPerson(Person::new));
        System.out.println(person.getPerson2(String::new));
    }


}

Stream

1. 流有3部分组成
	1. 源
	2. 零个或多个中间操作
	3. 终止操作
2. 流操作类型
	1. 惰性求值(无终止操作时,中间操作不进行)
	2. 及早求值
流一旦关闭或使用过,再次使用会报异常。

流的创建方式

public static void main(String[] args) {
    // 可变参数
    Stream<String> stream = Stream.of("a","b","ab");
    String[] strs = {"a", "c"};
    // 数组
    Stream<String> stream1 = Stream.of(strs);
    // Arrays方法
    Stream<String> stream2 = Arrays.stream(strs);
    // 集合方法
    List<String> list = new ArrayList<>();
    Stream<String> stream3 = list.stream();
}

example

public class StreamText {
    public static final List<Integer> fromUids = Arrays.asList(10031,10044,10045,10046,10055,10069);
    public static final List<Integer> toUids = Arrays.asList(10031,10044,10045,10046,10055,10069,1);
    public static void main(String[] args) {
        List<Transaction> transactionList = Arrays.asList(
                new Transaction(10031,10044),
                new Transaction(10031,10001),
                new Transaction(10044,1)
        );
        List<Transaction> collect = transactionList.stream().filter(a -> !(fromUids.contains(a.getFromUid()) && toUids.contains(a.getToUid())))
                .collect(Collectors.toList());
        System.out.println(collect);
    }

}
@Data
@AllArgsConstructor
class Transaction{
    private Integer fromUid;
    private Integer toUid;
}
public static void main(String[] args) {
        List<Integer> list = Arrays.asList(1,2,3,4,5,6);
        // 集合 *2 求和
        Integer sum = list.stream().map(a -> a * 2).reduce(0, Integer::sum);
        System.out.println(sum);
        // 组合List
        List<String> list = Arrays.asList("hi","hello");
        List<String> list1 = Arrays.asList("zs","ls","ww");
        list.stream().flatMap(item->list1.stream().map(item2 -> item + " " +item2)).forEach(System.out::println);
    }

Stream方法

public static void main(String[] args) {
    Stream<String> stream = Stream.of("hello","world","aaa");
    //转数组
    String[] strings = stream.toArray(String[]::new);
    //转集合
    List<String> collect = stream.collect(Collectors.toList());
    //LinkedList
    List<String> list = stream.collect(LinkedList::new,LinkedList::add,LinkedList::addAll);
    // 可以写多种形式
    List<String> linkedList = stream.collect(Collectors.toCollection(LinkedList::new));
    Set<String> set = stream.collect(Collectors.toSet());
    //拼接   结果:helloworldaaa
    String str = stream.collect(Collectors.joining());
    //映射  全部转为大写并输出
    stream.map(String::toUpperCase).forEach(System.out::println);
    //flatMap 将多级集合放入同一级使用
    List<List<Integer>> listList = Arrays.asList(Arrays.asList(1),Arrays.asList(2,3,4), Arrays.asList(5,6));
    listList.stream().flatMap(item->item.stream()).forEach(System.out::println);
    //iterate无限流  需要有终止条件
    Stream.iterate(1,a -> a+2).limit(5).reduce(Integer::sum).ifPresent(System.out::println);
    //mapToInt mapToLong mapToDouble  避免装箱拆箱的性能损耗
    Stream.iterate(1, a -> a + 2).limit(6).filter(a -> a > 2).mapToInt(a -> a * 2).skip(2).limit(2).sum();
    //IntSummaryStatistics 可以获取多个值
    IntSummaryStatistics intSummaryStatistics = Stream.iterate(1, a -> a + 2).limit(6).filter(a -> a > 2)
    .mapToInt(a -> a * 2).skip(2).limit(2).summaryStatistics();
        System.out.println(intSummaryStatistics.getSum());
        System.out.println(intSummaryStatistics.getAverage());
	// distinct 去重  根据equal方法判断
	Stream.of("a","a").distinct().forEach(System.out::println);
}

Stream分组

public class StreamGroupBy {
    public static void main(String[] args) {
        List<Dog> list = Lists.newArrayList(
                new Dog("xiaohua",1),
                new Dog("xiaohuang",2),
                new Dog("xiaohong",3),
                new Dog("xiaohua",3)
        );
        Map<String, List<Dog>> collect = list.stream().collect(Collectors.groupingBy(Dog::getName));
        //list没有数据时,返回map为空的map
		Map<String, Long> collect1 = list.stream().collect(Collectors.groupingBy(Dog::getName, Collectors.counting()));
		//获取平均值 等类似sql
		Map<String, Double> collect2 = list.stream().collect(Collectors.groupingBy(Dog::getName, Collectors.averagingDouble(Dog::getAge)));
		//分区 结果分为true和false两部分
		Map<Boolean, List<Dog>> collect3 = list.stream().collect(Collectors.partitioningBy(dog -> dog.getAge() >= 3));
    }
}
@Data
@AllArgsConstructor
class Dog{
    private String name;
    private Integer age;
}

Collect

1. collect: 收集器
2. Collector是collect方法的参数
3. Collector是一个接口,是一个可变的汇聚操作,将输入元素累积到一个可变的容器中,在所有元素处理完成后,将结果转为一个最终的表示,
	支持串行和并行两种执行方式。
4. Collectors是一个提供很多Collector实现的工具类

example

public static void main(String[] args) {
	list.stream().collect(Collectors.minBy(Comparator.comparingInt(Dog::getAge))).ifPresent(System.out::println);
	List<String> list = Arrays.asList("nihao","hello","world","hello world");
	//cccnihao,hello,world,hello worldaaa
	System.out.println(list.stream().collect(Collectors.joining(",","ccc","aaa")));
    list.sort(Comparator.comparingInt(String::length).thenComparing(Comparable::compareTo).reversed());
}

日期

1. jdk8之前使用Date、Calendar、SimpleDateFormat,有线程安全和使用不方便的缺点
2. jdk8之前可以封装DateUtils或者使用JodaTime

JodaTime

1. 引入joda-time jar包
<dependency>
    <groupId>joda-time</groupId>
    <artifactId>joda-time</artifactId>
    <!--spring-boot项目有对应版本-->
</dependency>

example

public static void main(String[] args) {
        DateTime dateTime = new DateTime();
        DateTime tomorrow = dateTime.plusDays(1);
        System.out.println(dateTime.toString("yyyy-MM-dd HH:mm:ss"));
        System.out.println(tomorrow.toString("yyyy-MM-dd HH:mm:ss"));
        System.out.println(dateTime.withDayOfMonth(1).toString("yyyy-MM-dd HH:mm:ss"));
        LocalDate localDate = new LocalDate();
        // 三个月前的最后一天
        System.out.println(localDate.minusMonths(3).dayOfMonth().withMaximumValue());
        // 两年前的三月
        System.out.println(localDate.minusYears(2).monthOfYear().setCopy(3));
    }

java.time.*

public static void main(String[] args) {
        //当前时间 yyyy-MM-dd
        LocalDate localDate = LocalDate.now();
        // 2019-10-1
        LocalDate localDate1 = LocalDate.of(2019, 10, 1);
        // 2019,10,1
        System.out.println(localDate1.getYear()+","+localDate1.getMonthValue()+","+localDate1.getDayOfMonth());
        MonthDay monthDay = MonthDay.now();
        MonthDay monthDay1 = MonthDay.from(localDate);
        // true  monthDay比较月和天(生日)
        System.out.println(monthDay.equals(monthDay1));
        // HH:mm:ss.SSS
        LocalTime localTime = LocalTime.now();
        // +2小时-20分钟
        System.out.println(localTime.plusHours(2).minusMinutes(20));
        //增加一个星期  俩种写法
        System.out.println(localDate.plusWeeks(1));
        System.out.println(localDate.plus(1, ChronoUnit.WEEKS));
        //日期比较
        boolean b = localDate.isAfter(localDate1);
        boolean b1 = localDate.isBefore(localDate1);
        System.out.println(localDate.isEqual(LocalDate.now()));
        LocalDateTime localDateTime = LocalDateTime.now();
        System.out.println(localDateTime.equals(new Date()));
        //获得两个日期相隔年月日
        Period period = Period.between(localDate, localDate1);
        System.out.println(period.getYears());
        System.out.println(period.getMonths());
        System.out.println(period.getDays());
        //获取两个时间天数间隔
		LocalDate now = LocalDate.now();
        LocalDate newYear = LocalDate.of(2020,1,25);
        System.out.println(newYear.toEpochDay()-now.toEpochDay());
		
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的使用 JDK 8 特性进行级联查询树的例子: ```java public class TreeNode { private Long id; private Long parentId; private String name; private List<TreeNode> children = new ArrayList<>(); // 构造函数、getter 和 setter 方法省略 // 添加子节点 public void addChild(TreeNode node) { children.add(node); } // 获取子节点 public List<TreeNode> getChildren() { return children; } // 级联查询树 public static List<TreeNode> buildTree(List<TreeNode> nodes) { Map<Long, TreeNode> nodeMap = nodes.stream().collect(Collectors.toMap(TreeNode::getId, Function.identity())); List<TreeNode> rootNodes = new ArrayList<>(); for (TreeNode node : nodes) { Long parentId = node.getParentId(); if (parentId == null) { rootNodes.add(node); } else { TreeNode parent = nodeMap.get(parentId); parent.addChild(node); } } return rootNodes; } } ``` 使用上述代码,我们可以将一个节点列表转换为树形结构。例如,如果我们有以下节点列表: ```java List<TreeNode> nodes = Arrays.asList( new TreeNode(1L, null, "A"), new TreeNode(2L, 1L, "B"), new TreeNode(3L, 1L, "C"), new TreeNode(4L, 2L, "D"), new TreeNode(5L, 2L, "E"), new TreeNode(6L, 3L, "F") ); ``` 我们可以使用 `TreeNode.buildTree(nodes)` 方法将其转换为树形结构: ```java List<TreeNode> rootNodes = TreeNode.buildTree(nodes); System.out.println(rootNodes); ``` 输出结果为: ``` [TreeNode(id=1, parentId=null, name=A, children=[TreeNode(id=2, parentId=1, name=B, children=[TreeNode(id=4, parentId=2, name=D, children=[]), TreeNode(id=5, parentId=2, name=E, children=[])]) TreeNode(id=3, parentId=1, name=C, children=[TreeNode(id=6, parentId=3, name=F, children=[])])])] ``` 这个例子中,我们使用了 Java 8 的 Lambda 表达式和 Stream API 来简化代码。其中,`Collectors.toMap()` 方法将节点列表转换为一个以节点 ID 为键、节点对象为值的 Map,方便后续查找父节点。然后,我们遍历节点列表,将每个节点添加到其父节点的 `children` 列表中,最终返回所有根节点。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值