JAVA 8新特性

1.lambda表达式

匿名内部类的出现是为了减少代码的书写,避免实例化类或者接口的冗余行为,就地构造,类似于Lambda表达式。

接口:

一个类可以实现多个接口,接口的成员变量默认是常量,方法是抽象方法,没有方法体。

别的类实现这个接口相当于继承,必须重写抽象方法。(JAVA8对接口增强,可以在接口中有函数体,子类可以重写,也可以不重写)

这时候如果有两个类实现一个接口,可以用接口=两个类,多态的思想,面向接口编程。

Lamda表达式只能简化函数式接口的匿名内部类(是接口,且只有一个抽象方法。)@FunctionalInterface注解的一定是函数接口。

参数类型可以省略;一个参数时括号可以省略;

方法体代码只有一行大括号可以省略,分号和return一定要省略;

public static void main(String[] args) {
    //父类对象指向子类对象,多态的思想
    Interface01 interface01 = new Interface01() {
        @Override
        public void show() {
            System.out.println("hello");
        }
    };
    //调用接口方法
    interface01.show();
}

Lambda

// 1. 不需要参数,返回值为 5  
() -> 5  
  
// 2. 接收一个参数(数字类型),返回其2倍的值  
x -> 2 * x  
  
// 3. 接受2个参数(数字),并返回他们的差值  
(x, y) -> x – y  
  
// 4. 接收2个int型整数,返回他们的和  
(int x, int y) -> x + y  
  
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)  
(String s) -> System.out.print(s)
  • Lambda 表达式主要用来定义行内执行的方法类型接口。我们使用各种类型的 Lambda 表达式来定义 MathOperation 接口的方法,然后我们定义了 operation 的执行。

  • lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量。

  • lambda 表达式的局部变量可以不用声明为 final,但是必须不可被后面的代码修改(即隐性的具有 final 的语义)

  • 在 Lambda 表达式当中不允许声明一个与局部变量同名的参数或者局部变量。

 2.数据结构

int[] array = new int[5];


List<String> arrayList = new ArrayList<>();
List<Integer> linkedList = new LinkedList<>();


Set<String> hashSet = new HashSet<>();
Set<Integer> treeSet = new TreeSet<>();


Map<String, Integer> hashMap = new HashMap<>();
Map<String, Integer> treeMap = new TreeMap<>();


Stack<Integer> stack = new Stack<>();
Queue<String> queue = new LinkedList<>();


PriorityQueue<Integer> minHeap = new PriorityQueue<>();
PriorityQueue<Integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());


class TreeNode {
    int val;
    TreeNode left;
    TreeNode right;
    TreeNode(int x) { val = x; }
}

Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。Collection 接口又有 3 种子类型,List、Set 和 Queue,再下面是一些抽象类,最后是具体实现类,常用的有 ArrayListLinkedListHashSet、LinkedHashSet、HashMap、LinkedHashMap 等等。

迭代器,比较器。

Stack<Integer> 尖括号中的数据类型必须是引用类型,大写的,要么就是int->Integer

3.Stream的使用

3.0 stream基础

stream是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。 “集合讲的是数据,Stream讲的是计算!”

  1. Stream关注的是对数据的运算,与CPU打交道,集合关注的是数据的存储,与内存打交道。
  2. Stream 自己不会存储元素。
  3. Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
  4. Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行

3.1 创建 stream

Optional类是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象。

//通过集合创建
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();


//通过数组创建
int[] array={1,2};
IntStream stream = Arrays.stream(array);


//通过集合本身创建
Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5, 6);

Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 3).limit(4);
stream2.forEach(System.out::println);

Stream<Double> stream3 = Stream.generate(Math::random).limit(3);
stream3.forEach(System.out::println);

3.2 Stream 的中间操作和终止操作

看分类并不一致,这里暂时记录一下常见的操作,可能之后熟悉了就比较好分辨。

遍历/匹配(终端)

(foreach/find/match):Stream也是支持类似集合的遍历和匹配元素的,只是Stream中的元素是以Optional类型存在的。Stream的遍历、匹配非常简单。

// 遍历输出符合条件的元素
        list.stream().filter(x -> x > 6).forEach(System.out::println);
        // 匹配第一个
        Optional<Integer> findFirst = list.stream().filter(x -> x > 6).findFirst();
        // 匹配任意(适用于并行流)
        Optional<Integer> findAny = list.parallelStream().filter(x -> x > 6).findAny();
        // 是否包含符合特定条件的元素
        boolean anyMatch = list.stream().anyMatch(x -> x < 6);
        System.out.println("匹配第一个值:" + findFirst.get());
        System.out.println("匹配任意一个值:" + findAny.get());
        System.out.println("是否存在大于6的值:" + anyMatch);

这里还用到了筛选filter,这应该是一个中间操作,里面是一个谓词,返回一个bool值。

聚合(终端)

(max/min/count):

        
Optional<String> max = list.stream().max(Comparator.comparing(String::length));

// 自然排序
        Optional<Integer> max = list.stream().max(Integer::compareTo);
// 自定义排序
		Optional<Integer> max2 = list.stream().max(new Comparator<Integer>() {
			@Override
			public int compare(Integer o1, Integer o2) {
				return o1.compareTo(o2);
			}
		});
long count = list.stream().filter(x -> x > 6).count();
映射(map/flatMap)

映射,可以将一个流的元素按照一定的映射规则映射到另一个流中。分为map和flatMap:

  • map:接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
  • flatMap:接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。
map(String::toUpperCase)
map(x -> x + 3)


        // 不改变原来员工集合的方式(值传递,不影响实参)
		List<Person> personListNew = personList.stream().map(person -> {
			Person personNew = new Person(person.getName(), 0, 0, null, null);
			personNew.setSalary(person.getSalary() + 10000);
			return personNew;
		}).collect(Collectors.toList());


		// 改变原来员工集合的方式(引用)
		List<Person> personListNew2 = personList.stream().map(person -> {
			person.setSalary(person.getSalary() + 10000);
			return person;
		}).collect(Collectors.toList());
归约(reduce)(终端)

归约,也称缩减,顾名思义,是把一个流缩减成一个值,能实现对集合求和、求乘积和求最值操作。

Optional<Integer> sum = list.stream().reduce((x, y) -> x + y);
		// 求和方式2
		Optional<Integer> sum2 = list.stream().reduce(Integer::sum);
收集(collect)(终端)

collect,收集,可以说是内容最繁多、功能最丰富的部分了。从字面上去理解,就是把一个流收集起来,最终可以是收集成一个值也可以收集成一个新的集合。

collect主要依赖java.util.stream.Collectors类内置的静态方法。

归集(toList/toSet/toMap)

因为流不存储数据,那么在流中的数据完成处理后,需要将流中的数据重新归集到新的集合里。toList、toSet和toMap比较常用,另外还有toCollection、toConcurrentMap等复杂一些的用法。

还有别的静态方法:提取,limit,skip,最大值最小值,归约,分组,求平均,求和等等。

  • 15
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值