java8新特性---大总结--建议点赞、收藏!!!

1、Lambda表达式------也叫做 函数式编程

Lambda是一个匿名函数,可以理解为一段可以(像数据一样)传递的代码。可以使代码更简介更灵活
使用lambda表达式有4个知识点

第一个、lambda表达式的格式()->{},只有函数式接口才能使用这种格式

函数式接口接口只能有一个抽象方法、可以有多个defaultstatic方法这样的接口才能算是函数式接口
接口中只有一个方法声明,例如Runnable接口,可以使用lambda表达式
使用方式 ()->{}

new Thread(()->{System.out.println("lambda表达式测试");},"lambda").start();
//Runable来自java.lang没有返回值
Runnable runnable=()->{ System.out.println("lambda测试"); };
//Callable来自java.util.concurrent 有返回值,需要有一个泛型,例如传入Integer作为泛型
Callable<Integer> callable=()->{return 1;};

第二个

java8中,接口如果只有一个方法声明,则会默认在编译的过程中会加上
@FunctionalInterface注解,相当于隐式的声明
例如

@FunctionalInterface
interface demo{
    int add(int x,int y);
}

第三个

java8中允许在接口内写实现好的方法,但需要加上default声明,实现的方法允许多个,但只能有一个方法声明没有实现。

@FunctionalInterface
interface demo{
    int add(int x,int y);
    //允许多个default声明的方法实现
    default int sub(int x,int y){
        return x - y;
    }
    default int sub_reverse(int x,int y){
        return y - x;
    }
}

第四个

java8中还允许有多个static声明的方法

@FunctionalInterface
interface demo{
    int add(int x,int y);
    //多个static
    static double div(int x,int y){
        return x / y;
    }
    static int muti(int x,int y){
        return x * y;
    }
}

java8内置的四个函数接口

都在java.util.function包下

函数式接口 参数列表 返回类型 用途
Consumer T void 对类型T的对象应用和操作,包含方法void accept(T t)
Supplier void 返回类型为T的对象,包含方法T get()
Function T R 对类型T的对象应用和操作并返回结果R,包含方法R apply(T t)以及default声明的实现方法
Predicate T boolean 确定类型T的对象是否满足约束,包含方法boolean test(T t)
Consumer使用案例
//Consumer 消费型接口 :
@Test
public void test1(){
	happy(10000, (m) -> System.out.println("每次消费:" + m + "元"));
} 

public void happy(double money, Consumer<Double> con){
	con.accept(money);
}
Supplier使用案例
//Supplier 供给型接口 :
@Test
public void test2(){
	List<Integer> numList = getNumList(10, () -> (int)(Math.random() * 100));
	for (Integer num : numList) {
		System.out.println(num);
	}
}

//需求:产生指定个数的整数,并放入集合中
public List<Integer> getNumList(int num, Supplier<Integer> sup){
	List<Integer> list = new ArrayList<>();
	for (int i = 0; i < num; i++) {
		Integer n = sup.get();
		list.add(n);
	}
	return list;
}
Function使用案例
//Function 函数型接口:
@Test
public void test3(){
	String newStr = strHandler("\t\t\t 尚硅谷威武   ", (str) -> str.trim());
	System.out.println(newStr);
	String subStr = strHandler("尚硅谷威武", (str) -> str.substring(2, 5));
	System.out.println(subStr);
}

//需求:用于处理字符串
public String strHandler(String str, Function<String, String> fun){
	return fun.apply(str);
}
Predicate使用案例
//Predicate 断言型接口:
@Test
public void test4(){
	List<String> list = Arrays.asList("Hello", "atguigu", "Lambda", "www", "ok");
	List<String> strList = filterStr(list, (s) -> s.length() > 3);
	for (String str : strList) {
		System.out.println(str);
	}
}

//需求:将满足条件的字符串,放入集合中
public List<String> filterStr(List<String> list, Predicate<String> pre){
	List<String> strList = new ArrayList<>();
	for (String str : list) {
		if(pre.test(str)){
			strList.add(str);
		}
	}
	return strList;
}

同理java8中还内置了截图中的这些函数式接口
具体的内容查看java.util.function包下面的接口内容
java8新特性---大总结--建议点赞、收藏!!!_第1张图片

2、Stream流----对数据进行操作

创建Stream

方式一、 集合类,实现了Collection类的子类都可以创建集合类,通过集合自带的stram方法获取
java8新特性---大总结--建议点赞、收藏!!!_第2张图片
java8新特性---大总结--建议点赞、收藏!!!_第3张图片

常用的集合类有

1、ArrayList(初始容量10,达到扩容因子则会扩容至原先的1.5倍)
java8新特性---大总结--建议点赞、收藏!!!_第4张图片
java8新特性---大总结--建议点赞、收藏!!!_第5张图片
2、CopyOnWriteArrayList(解决多线程写入同一个ArrayList异常的解决方案、上个线程还没写入成功就被另一个线程写入。抛出java.util.ConcurrentModificationException异常)

为了让其出java.util.ConcurrentModificationException异常,则在线程类内部加个等待200毫秒,这样必出异常

public static void main(String[] args) {
   List<String> list = new ArrayList<>();

   for (int i = 0; i < 30; i++) {
       new Thread(() -> {
           try {
               TimeUnit.MILLISECONDS.sleep(200);//让其必出异常做的等待
           } catch (InterruptedException e) {
               e.printStackTrace();
           }
           list.add(UUID.randomUUID().toString().substring(0, 3));
           System.out.println(list.size()+""+list);
       }, String.valueOf(i)).start();
   }
}

3、LinkedList(链表初始容量0,没有最大容量)
4、Vector(初始容量10、和ArrayList一样的最大值。区别是add方法加了synchronized是线程安全的,但是这种方式对性能损耗太大!线程安全使用CopyOnWriteArrayList解决问题最好,不使用Vector,除非是个小程序不需要考虑性能问题)

5、HashSet(底层是HashMap)
6、CopyOnWriteArraySetCopyOnWriteArrayList一样的作用是为了解决多线程安全问题设置的

7、HashMap(初始容量1左移4位就是 24=16,最大容量230,超过了则设置为Integer.MAX_VALUE也就是231。看后面截图,容量因子0.75达到了容量因子则会扩容,会扩容到原先的2倍)
java8新特性---大总结--建议点赞、收藏!!!_第6张图片
Integer.MAX_VALUE=0x7fffffff也就是2的31次方
java8新特性---大总结--建议点赞、收藏!!!_第7张图片
8、ConcurrentHashMap(和前面一样为了解决java.util.ConcurrentModificationException异常)
9、TreeMap(是一种红黑树,关于TreeMap看到一篇博客,里面有详细讲解https://www.jianshu.com/p/2dcff3634326)

Collections和Collection的区别

Collections是集合的一个工具类
List排序

void reverse(List list)//反转
void shuffle(List list),  //随机排序
void sort(List list),     //按自然排序的升序排序
void sort(List list, Comparator c);  //定制排序,由Comparator控制排序逻辑
void swap(List list, int i , int j)  //交换两个索引位置的元素
void rotate(List list, int distance) /*旋转。当distance为正数时,
将list后distance个元素整体移到前面。当distance为负数时,将 list的前distance个元素整体移到后面。*/

List搜索和替换

//对List进行二分查找,返回索引,注意List必须是有序的
int binarySearch(List list, Object key)

//根据元素的自然顺序,返回最大的元素。 类比int min(Collection coll)
int max(Collection coll),

//根据定制排序,返回最大元素,排序规则由Comparatator类控制。
//类比int min(Collection coll, Comparator c)
int max(Collection coll, Comparator c)

void fill(List list, Object obj)      //用元素obj填充list中所有元素
int frequency(Collection c, Object o) //统计元素出现次数

/* 统计targe在list中第一次出现的索引,找不到则返回-1,
类比int lastIndexOfSubList(List source, list target).*/
int indexOfSubList(List list, List target)
boolean replaceAll(List list, Object oldVal, Object newVal)// 用新元素替换旧元素。

Collection是一个接口,定义了上面ArrayList这类集合类的接口。对于实现Collection接口,子类都可以使用Collections对集合进行一系列操作。

集合类获取Stream的4种方式

//方式一、通过集合的方式获取,也就是上面记录的
List<String> list=new ArrayList<>();
Stream<String> stream1 = list.stream();

//方式二、Arrays的静态方法stream()获取
Integer[] integers=new Integer[10];
Stream<Integer> stream2 = Arrays.stream(integers);

//方式三、Stream的静态方法of
Stream<Integer> stream3 = Stream.of(12, 13, 14);

//方式四、创建无限流
//1、迭代
Stream<Integer> stream4 = Stream.iterate(0, x -> x + 2);
stream4.limit(10).forEach(System.out::println);//流进行操作,限制流的数量
//2、生成
Stream.generate(()-> Math.random()).limit(5).forEach(System.out::println);

常见的Stream操作

筛选和切片

filter传入一个断言接口
例如获取奇数,过滤偶数,按照三步
创建流 操作流 终止流

//1、创建流
List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);//可以将数字换成对象,然后泛型改成对应的对象即可
//2、操作流
/*可以换成对应的比较,比如  对象::getXXX==某个值 或者>,<这类比较,
使用的是Predicate断言接口,boolean test(T t);。*/
Stream<Integer> integerStream = integers.stream().filter((e) -> e % 2 == 1);

//3、终止流,进行输出
integerStream.forEach(System.out::println);//输出 1 3 5
截断流

limit
limit会造成短路现象,也就是当limit达到条件时之后的迭代操作就不会生效

List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);//可以讲数字换成对象,然后泛型改成对应的对象即可
Stream<Integer> integerStream = integers.stream().filter((e) -> e % 2 == 1).limit(1);//可以换成对应的比较,比如对象.getXXX判断
integerStream.forEach(System.out::println);//只输出 1
跳过

skip跳过,这个好理解,跳过前面的指定多少条记录

List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5);//可以讲数字换成对象,然后泛型改成对应的对象即可
Stream<Integer> integerStream = integers.stream().filter((e) -> e % 2 == 1).skip(1).limit(1);//可以换成对应的比较,比如对象.getXXX判断
integerStream.forEach(System.out::println);//只输出 3
去重

distinct去重

List<Integer> integers = Arrays.asList(1, 1, 2, 3, 4, 5);//可以讲数字换成对象,然后泛型改成对应的对象即可
Stream<Integer> integerStream = integers.stream().filter((e) -> e % 2 == 1).distinct().skip(1).limit(1);//可以换成对应的比较,比如对象.getXXX判断
integerStream.forEach(System.out::println);//只输出 3
映射

map需要传入一个Function接口,会将集合的每一个元素都应用到函数式接口的参数上
如果将下面的"aaa","bbb"换成对象,可以在map传入对象::getXXX来将指定的字段提取出来

List<String> list = Arrays.asList("aaa", "bbb", "ccc", "ddd");//可以讲数字换成对象,然后泛型改成对应的对象即可
list.stream().map((str) -> {
            return str.toUpperCase();}
).forEach(System.out::println);

两天内会将其补充完全。
flatMap将多个流合并成一个大流


你可能感兴趣的:(#,java8新特性,#,Java高级笔记)