JAVA 1.8新特性

JAVA 1.8新特性

1 新特性介绍

# 什么是JAVA 1.8新特性?
2014年Oracle公司更新jdk版本后新增的特性
# 作用?
lambda表达式(简化匿名内部类代码)、方法引用(多用于流Stream)、新日期API

2 lambda表达式

2.1 lambda表达式使用

package com.qf.a_lambda;

import java.io.File;
import java.io.FileFilter;
import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

import org.junit.Test;

/**
 * lambda表达式
 * - 简化匿名内部类的代码,在这里,该匿名内部类实现必须是函数式接口
 * - 标记型接口:接口中没有方法,只作为标记使用,比如Serializable接口
 * - 函数式接口:接口中只有一个方法,通常提供一个功能作为方法参数的形式传入,比如Runnable接口
 */
@SuppressWarnings("all")
public class LambdaTest {
	
	// 1 函数式接口中的方法没有参数且没有返回值
	@Test
	public void test1() {
		// 1.1 普通方式的线程任务
		Runnable r1 = new Runnable() {
			@Override
			public void run() {
				System.out.println("子线程启动...");
			}
		};
		
		// 1.2 lambda表达式的线程任务(代码实现一般只有一行时)
		Runnable r2 = () -> System.out.println("子线程启动...");
		
		// 1.3 lambda表达式的线程任务(代码实现一般只有一行或多行时)
		Runnable r3 = () ->{
			System.out.println("子线程启动...");
		};
		
		new Thread(r3).start();
	}
	
	// 2 函数式接口中的方法有两个参数且有返回值
	@Test
	public void test2() {
		// 2.1 普通方式的比较器(带上泛型)
		Comparator<Integer> c1 = new Comparator<Integer>() {
			@Override
			public int compare(Integer o1, Integer o2) {
				return o1 - o2;
			}
		};
		
		// 2.2 lambda表达式的比较器(带上泛型,代码实现一般只有一行时)
		Comparator c2 = (Object o1,Object o2) -> (Integer)o1 -(Integer)o2;  // 不带泛型,很麻烦
		Comparator<Integer> c3 = (o1, o2) -> o1 - o2;
		
		// 2.3 lambda表达式的比较器(带上泛型,代码实现一般只有一行或多行时不能省略return关键字)
		Comparator<Integer> c4 = (o1, o2) ->{
			return o1 - o2;
		};
		
		Set<Integer> set = new TreeSet<>(c4);
		set.add(3);
		set.add(4);
		set.add(1);
		System.out.println(set);
	}
	
	// 3 函数式接口中的方法有一个参数且没有返回值
	@Test
	public void test3() {
		// 3.1 普通方式的文件过滤器(带上泛型)
		FileFilter f1 = new FileFilter() {
			@Override
			public boolean accept(File pathname) {
				if(pathname.isFile() && pathname.getName().endsWith(".txt")) {
					return true;
				}
				return false;
			}
		};
		
		// 3.2 lambda表达式的比较器(带上泛型,代码实现一般只有一行或多行时不能省略return关键字)
		FileFilter f2 = pathname ->{
			if(pathname.isFile() && pathname.getName().endsWith(".txt")) {
				return true;
			}
			return false;
		};
		
		File file = new File("a");  // 当前工程下的a目录
		File[] files = file.listFiles(f2);
		for(File f : files) {
			System.out.println(f.getName());
		}
	}
}

2.2 jdk常用接口类型

package com.qf.a_lambda;

import java.util.Random;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

/**
 * jdk常用接口类型
 */
public class OfferInterfaceTest {
	public static void main(String[] args) {
		// 1 消费型接口(方法有参数,没有返回值)
		Consumer<Integer> c1 = new Consumer<Integer>() {
			@Override
			public void accept(Integer t) {
				System.out.println("t="+t);
			}
		};
		c1.accept(100);
		
		Consumer<Integer> c2 = t -> System.out.println("t="+t);
		c2.accept(200);
		
		// 2 供给型接口(方法无参,有返回值)
		Supplier<Integer> s1 = new Supplier<Integer>() {
			@Override
			public Integer get() {
				return new Random().nextInt(10);
			}
		};
		System.out.println(s1.get());
		
		Supplier<Integer> s2 = () -> new Random().nextInt(10);
		System.out.println(s2.get());
		
		// 3 函数型接口(只有一个方法)
		Function<String, Integer> f1 = new Function<String, Integer>() {
			@Override
			public Integer apply(String t) {
				return t.length();
			}
		};
		System.out.println(f1.apply("Hello"));
		
		Function<String, Integer> f2 = t -> t.length();
		System.out.println(f2.apply("World"));
		
		// 4 断言型接口(有参数,返回boolean类型)
		Predicate<Integer> p1 = new Predicate<Integer>() {
			@Override
			public boolean test(Integer t) {
				return t == 3;
			}
		};
		System.out.println(p1.test(3));
		
		Predicate<Integer> p2 = t -> t == 3;
		System.out.println(p2.test(4));
	}
}

2.3 lambda表达式案例

package com.qf.a_lambda;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

/**
 * 集合中放入不同长度的字符串,通过lambda表达式的方法获取长度为3的字符串或长度大于4的字符串
 */
public class MyTest {
	public static void main(String[] args) {
		List<String> srcList = Arrays.asList(new String[] {"abc","bcd","ghdfe"});
		// 长度等于3
		List<String> destList = new GetListLength().getLength(srcList, t -> t.length() == 3);
		System.out.println(destList);
		// 长度大于4
		List<String> destList2 = new GetListLength().getLength(srcList, t -> t.length() > 4);
		System.out.println(destList2);
	}	
}

/**
 * 获取集合长度的实现类
 */
class GetListLength implements GetLengthable{
	@Override
	public List<String> getLength(List<String> srcList, Predicate<String> predicate) {
		if(srcList != null) {
			List<String> list = new ArrayList<>();
			for(String str : srcList) {
				if(predicate.test(str)) {
					list.add(str);
				}
			}
			return list;
		}
		
		return null;
	}
}

/**
 * 获取集合长度的接口
 */
interface GetLengthable{
	/**
	 * 获取长度
	 * @param srcList 原集合
	 * @param predicate 断言型接口
	 * @return 目标集合
	 */
	List<String> getLength(List<String> srcList, Predicate<String> predicate);
}

3 方法引用(多用于流Stream)

3.1 流的创建方式

package com.qf.a_lambda;
/**
 * Stream
 * -流,类似于集合。集合的作用的存储数据,而流的作用则是存储集合或数组的操作过程
 */

import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import org.junit.Test;

public class StreamTest {

	// 1 通过集合获取流对象
	@Test
	public void test1() {
		List<Integer> list = Arrays.asList(new Integer[] {22,44,66,33});
		
		// 1.1 获取流对象,注意,这里forEach会关闭流,只能调一次
		Stream<Integer> stream = list.stream();
//		Stream<Integer> stream2 = list.parallelStream();  // 多线程,会打乱元素位置
		
//		stream.forEach(new Consumer<Integer>() {     // 普通方式
//			@Override
//			public void accept(Integer t) {
//				System.out.println(t);
//			}
//		});
		
//		stream.forEach(t -> System.out.println(t));  // lambda方式
		
		stream.forEach(System.out::println);         // 1.2 方法引用
	}
	
	// 2 通过数组的工具类Arrays获取流对象
	@Test
	public void test2() {
		Arrays.stream(new int[] {3,2,4}).forEach(System.out::println);
	}
	
	// 3 通过Stream类获取流对象
	@Test
	public void test3() {
		// 3.1 of
		Stream.of(3,4,2).forEach(System.out::println);
		
		// 3.2 iterate
		Stream.iterate(3, t -> t + 2).limit(3).forEach(System.out::println);
		
		// 3.3 generate
		Stream.generate(() -> new Random().nextInt(10)).limit(4).forEach(System.out::println);
	}
	
	// 4 通过IntStream类获取流对象(LongStream和DoubleStream类似)
	@Test
	public void test4() {
		// 4.1 of
		IntStream.of(3,4,2).forEach(System.out::println);
		
		// 4.2 range -> [3, 6)
		IntStream.range(3, 6).forEach(System.out::println);
		
		// 4.3 rangeClosed -> [3, 6]
		IntStream.rangeClosed(3, 6).forEach(System.out::println);
	}
}

3.2 流的中间操作

package com.qf.a_lambda;
/**
 * 流的常用中间操作
 * - filter, limit, skip, distinct, sorted, map, parallel
 */

import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.stream.IntStream;

import org.junit.Test;

public class StreamMidTest {
	private List<Student> list = Arrays.asList(new Student[] {
			new Student("sunwukong", 500), new Student("tangsen",20),
			new Student("bajie",600), new Student("shasen",660),
			new Student("bajie",600)});
	
	// 1 filter 过滤
	@Test
	public void test1() {
		list.stream().filter(p -> p.getName().length() != 5).forEach(System.out::println);
	}
	
	// 2 limit 限制
	@Test
	public void test2() {
		IntStream.generate(() -> new Random().nextInt(10)).limit(4).forEach(System.out::println);
	}
	
	// 3 skip 跳过
	@Test
	public void test3() {
		list.stream().skip(2).forEach(System.out::println);
	}
	
	// 4 distinct 去重
	@Test
	public void test4() {
		// 注意:元素需重写hashcode方法和equals方法
		list.stream().distinct().forEach(System.out::println);
	}
	
	// 5 sorted 排序
	@Test
	public void test5() {
		list.stream().sorted((p1, p2) -> p1.getAge() - p2.getAge()).forEach(System.out::println);
	}
	
	// 6 map 映射
	@Test
	public void test6() {
		list.stream().map(p -> p.getName()).forEach(System.out::println);
	}
	
	// 7 parallel 多线程,性能提供,元素位置杂乱
	@Test
	public void test7() {
		list.stream().parallel().forEach(System.out::println);
	}
}

class Student{
	private String name;
	private Integer age;
	
	public Student() {
	}
	
	public Student(String name, Integer age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((age == null) ? 0 : age.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		if (age == null) {
			if (other.age != null)
				return false;
		} else if (!age.equals(other.age))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
	
}

3.3 流的最终操作

package com.qf.a_lambda;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import org.junit.Test;

/**
 * 流的常用最终操作
 * - forEach, min, max, count, reduce, collect
 */
public class StreamFinalTest {
	private List<Student2> list = Arrays.asList(new Student2[] {
			new Student2("sunwukong", 500), new Student2("tangsen",20),
			new Student2("bajie",600), new Student2("shasen",660),
			new Student2("bajie",600)});
	
	// 1 forEach 循环遍历
	@Test
	public void test1() {
		list.stream().forEach(System.out::println);
	}
	
	// 2 min 求最小数
	@Test
	public void test2() {
		System.out.println(list.stream().min((s1, s2) -> s1.getAge() -s2.getAge()).get());
	}
	
	// 3 max 最大数
	@Test
	public void test3() {
		System.out.println(list.stream().max((s1, s2) -> s1.getAge() -s2.getAge()).get());
	}
	
	// 4 count 计数量
	@Test
	public void test4() {
		System.out.println(list.stream().count());
	}
	
	// 5 reduce 汇总
	@Test
	public void test5() {
		System.out.println(list.stream().map(s -> s.getAge()).reduce((a1, a2) -> a1 + a2).get());
	}
	
	// 6 collect 返回集合
	@Test
	public void test6() {
		System.out.println(list.stream().map(s -> s.getName()).collect(Collectors.toSet()));
	}
}

class Student2{
	private String name;
	private Integer age;
	
	public Student2() {
	}
	
	public Student2(String name, Integer age) {
		this.name = name;
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getAge() {
		return age;
	}

	public void setAge(Integer age) {
		this.age = age;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((age == null) ? 0 : age.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student2 other = (Student2) obj;
		if (age == null) {
			if (other.age != null)
				return false;
		} else if (!age.equals(other.age))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "Student [name=" + name + ", age=" + age + "]";
	}
	
}

4 新日期API

package com.qf.a_lambda;
/**
 * 新日期API
 * -LocalDate, LocalTime, LocalDateTime, Instant, ZoneId
 */

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;

import org.junit.Test;

public class NewDateTest {
	
	// 1 LocalDate 当前日期
	@Test
	public void localDateTest() {
		LocalDate localDate = LocalDate.now();
		// 当前日期
		System.out.println(localDate);
	}
	
	// 2 LocalTime 当前时间
	@Test
	public void localTimeTest() {
		LocalTime localTime = LocalTime.now();
		// 当前时间
		System.out.println(localTime);
	}
	
	// 3 LocalDateTime 当前日期时间
	@Test
	public void LocalDateTimeTest() {
		LocalDateTime localDateTime = LocalDateTime.now();
		// 当前日期时间
		System.out.println(localDateTime);
		// 年份
		System.out.println(localDateTime.getYear());
		// 月份,注意:这里月份从1开始,与Calendar日历类不同
		System.out.println(localDateTime.getMonth().getValue());
		// 日
		System.out.println(localDateTime.getDayOfMonth());
		// 时
		System.out.println(localDateTime.getHour());
		// 分
		System.out.println(localDateTime.getMinute());
		// 秒
		System.out.println(localDateTime.getSecond());
	}
	
	// 4 Instant 时间戳
	@Test
	public void InstantTest() {
		Instant instant = Instant.now();
		// 当前时间戳
		System.out.println(instant);
	}
	
	// 5 ZoneId 时区
	@Test
	public void ZoneIdTest() {
		ZoneId zoneId = ZoneId.systemDefault();
		// 当前时区
		System.out.println(zoneId);
	}
	
	// 6 Date -> Instant -> LocalDateTime 转换
	@Test
	public void DateFormatTest() {
		Date date = new Date();
		Instant instant = date.toInstant();
		LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, ZoneId.systemDefault());
		System.out.println(localDateTime);
	}
	
	// 7 LocalDateTime -> Instant -> Date 转换
	@Test
	public void LocalDateTimeFormatTest() {
		LocalDateTime localDateTime = LocalDateTime.now();
		Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
		Date date = Date.from(instant);
		System.out.println(date);
	}
	
	// 8 DateTimeFormatter 带格式日期
	@Test
	public void DateTimeFormatterTest() {
		DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
		// 日期转字符串
		String datetime = dtf.format(LocalDateTime.now());
		System.out.println(datetime);
	}
}

5 结语

结语,因为官方无节制地限制博客的上传,我新写的博客将在博客园上传,地址https://www.cnblogs.com/lll919397/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值