Java 1.8 新特性

参考链接:

https://blog.csdn.net/haiyoung/article/details/52693212

一、接口的默认方法

使用default方法我们可以添加一个方法的实现到接口中。

public interface Formula {
	
	double calculate(int a);
	
	default double sqrt(int a) {
		return Math.sqrt(a);
	}

}

public class FormulaImpl implements Formula {

	public static void main(String[] args) {
		FormulaImpl formulaImpl = new FormulaImpl();
		double result1 = formulaImpl.calculate(100);
		double result2 = formulaImpl.sqrt(16);
		System.out.println("result1: " + result1); // 100.0
		System.out.println("result2: " + result2); // 4.0
		
	}

	@Override
	public double calculate(int a) {
		return sqrt(a * 100);
	}

}

二、Lambda表达式

使用Lambda表达式对List集合进行排序

List<String> names = Arrays.asList("peter", "anna", "mike", "xenia");
		
		// traditional way
		Collections.sort(names, new Comparator<String>(){
			@Override
			public int compare(String a, String b) {
//				return b.compareTo(a);
				return a.compareTo(b);
			}
		});
		System.out.println("traditional way names: " + names.toString());
		
		// Java 8 lambda way
		Collections.sort(names, (String a, String b) -> {
			return a.compareTo(b);
		});
		System.out.println("Java 8 lambda way names: " + names.toString());
		
		// Java 8 lambda way 2
		Collections.sort(names, (String a, String b) -> a.compareTo(b));
		System.out.println("Java 8 lambda way 2 names: " + names.toString());
		
		// Java 8 lambada way 3, only one line code, remove {} and return, even parameter type
		Collections.sort(names, (a, b) -> a.compareTo(b));
		System.out.println("Java 8 lambda way 3 names: " + names.toString()); 

运行结果:

traditional way names: [anna, mike, peter, xenia]
Java 8 lambda way names: [anna, mike, peter, xenia]
Java 8 lambda way 2 names: [anna, mike, peter, xenia]
Java 8 lambda way 3 names: [anna, mike, peter, xenia]

三、函数式接口

@FunctionalInterface

interface Converter<F, T> {
		T convert(F from);
	}
//		Converter<String, Integer> converter = (from) -> Integer.valueOf(from);
		Converter<String, Integer> converter = Integer::valueOf;
		Integer converted = converter.convert("123");
		
		Converter<String, Double> converter2 = (from) -> Double.valueOf(from);
		Double converted2 = converter2.convert("123.54");
		

四、方法与构造函数引用

public class Person {
	String firstName;
	String lastName;
	
	Person(){}
	
	Person(String firstName, String lastName) {
		this.firstName = firstName;
		this.lastName = lastName;
	}
	
	Person(String firstName) {
		this.firstName = firstName;
		this.lastName = "Liang";
	}
	
	@Override
	public String toString() {
		return "Person [firstName=" + firstName + ", lastName=" + lastName + "]";
	}


	interface PersonFactory<P extends Person> {
		P create(String firstName, String lastName);
	}
	
	public static void main(String[] args) {
		PersonFactory<Person> personFactory = Person::new;
		Person person = personFactory.create("Perter", "Parker");
		System.out.println("person: " + person.toString());
        }
}

五、Lambda 作用域

在lambda表达式中访问外层作用域和老版本的匿名对象中的方式很相似。你可以直接访问标记了final的外层局部变量,或者实例的字段以及静态变量。

六、访问局部变量

//		final int num = 1;
		int num = 1; // don't allow to modify this variable
		Converter<Integer, String> converter3 = (from) -> String.valueOf(from + num);
		String converted3 = converter3.convert(2);
		
		System.out.println("converted: " + converted); // 123
		System.out.println("converted2: " + converted2); // 123.54
		System.out.println("converted3: " + converted3); // 3

七、访问对象字段与静态变量


public class Lambda4 {
	static int outerStaticNum;
	int outerNum;
	
	interface Converter<F, T> {
		T convert(F from);
	}
	
	void testScopes() {
		Converter<Integer, String> stringConverter1 = (from) -> {
			outerNum = 23;
			return String.valueOf(from);
		};
		
		Converter<Integer, String> stringConverter2 = (from) -> {
			outerNum = 72;
			return String.valueOf(from);
		};
		
	}

}

八、访问接口的默认方法

Predicate 接口

Predicate 接口只有一个参数,返回boolean类型。该接口包含多种默认方法来将Predicate组合成其他复杂的逻辑(比如:与,或,非):

// Predicate interface
		Predicate<String> predicate = (s) -> s.length() > 0;
		
		System.out.println(predicate.test("foo")); // true
		System.out.println(predicate.negate().test("foo")); // false
		
		Predicate<Boolean> nonNull = Objects::nonNull;
		Predicate<Boolean> isNull = Objects::isNull;
		
		Predicate<String> isEmpty = String::isEmpty;
		Predicate<String> isNotEmpty = isEmpty.negate();

Function 接口

// Function interface
		Function<String, Integer> toInteger = Integer::valueOf;
		Function<String, String> backToString = toInteger.andThen(String::valueOf);
		
		System.out.println(backToString.apply("123")); // 123

Supplier 接口

// Supplier interface
		Supplier<Person> personSupplier = Person::new;
		personSupplier.get();

Consumer 接口

// Consumer interface
		Consumer<Person> greeter = (p) ->
		System.out.println("Hello, " + p.firstName); // Hello, Luke
		greeter.accept(new Person("Luke", "Sky"));

Comparator 接口

// Comparator interface
		Comparator<Person> comparator = (p1, p2) ->
		p1.firstName.compareTo(p2.firstName);
		
		Person p1 = new Person("John", "Doe");
		Person p2 = new Person("Alice", "Wonderland");

		System.out.println(comparator.compare(p1, p2)); // 9
		System.out.println(comparator.reversed().compare(p1, p2)); // -9

Optional 接口

Optional 不是函数是接口,这是个用来防止NullPointerException异常的辅助类型,这是下一届中将要用到的重要概念,现在先简单的看看这个接口能干什么:

Optional 被定义为一个简单的容器,其值可能是null或者不是null。在Java 8之前一般某个函数应该返回非空对象但是偶尔却可能返回了null,而在Java 8中,不推荐你返回null而是返回Optional。

// Optional interface
		Optional<String> optional = Optional.of("bam");
		
		System.out.println(optional.isPresent()); // true
		System.out.println(optional.get()); // bam
		System.out.println(optional.orElse("fallback")); // bam
		
		optional.ifPresent((s) -> System.out.println(s.charAt(0))); // b

Stream 接口

java.util.Stream 表示能应用在一组元素上一次执行的操作序列。Stream 操作分为中间操作或者最终操作两种,最终操作返回一特定类型的计算结果,而中间操作返回Stream本身,这样你就可以将多个操作依次串起来。Stream 的创建需要指定一个数据源,比如 java.util.Collection的子类,List或者Set, Map不支持。Stream的操作可以串行执行或者并行执行。

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

public class StreamDemo {

	public static void main(String[] args) {
		List<String> stringCollection = new ArrayList<>();
		stringCollection.add("ddd2");
		stringCollection.add("aaa2");
		stringCollection.add("bbb1");
		stringCollection.add("aaa1");
		stringCollection.add("bbb3");
		stringCollection.add("ccc");
		stringCollection.add("bbb2");
		stringCollection.add("ddd1");
		
		// Filter
		stringCollection.stream()
			.filter((s) -> s.startsWith("a"))
			.forEach(System.out::println); // forEach is final operation
		
		// Sort
		stringCollection.stream()
			.sorted()
			.filter((s) -> s.startsWith("a"))
			.forEach(System.out::println);
		
		System.out.println("stringCollection: " + stringCollection.toString());
		
		// Map
		stringCollection.stream()
			.map(String::toUpperCase)
			.sorted((a, b) -> b.compareTo(a))
			.forEach(System.out::println);
		
		// Match
		boolean anyStartsWithA = 
				stringCollection.stream()
					.anyMatch((s) -> s.startsWith("a"));
		System.out.println(anyStartsWithA);
		
		boolean allStartsWithA = 
				stringCollection.stream()
					.allMatch((s) -> s.startsWith("a"));
		System.out.println(allStartsWithA);
		
		boolean noneStartsWithZ = 
				stringCollection.stream()
					.noneMatch((s) -> s.startsWith("z"));
		System.out.println(noneStartsWithZ);
		
		// Count final operation
		long startWithB = 
				stringCollection.stream()
					.filter((s) -> s.startsWith("b"))
					.count();
		System.out.println(startWithB);
		
		// Reduce final operation
		Optional<String> reduced = 
				stringCollection.stream()
					.sorted()
					.reduce((s1, s2) -> s1 + "~" + s2);
		reduced.ifPresent(System.out::println);
		
	}

}

并行Streams

import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

public class ParallelStream {
	
	public static void main(String[] args) {
		int max = 1000000;
		List<String> values = new ArrayList<>(max);
		for (int i=0; i<max; i++) {
			UUID uuid = UUID.randomUUID();
			values.add(uuid.toString());
		}
		
		// serial and parrel sort
		long t0 = System.nanoTime();
		
//		long count = values.stream().sorted().count(); // serial
		long count = values.parallelStream().sorted().count(); // parallel
		System.out.println(count);
		
		long t1 = System.nanoTime();
		
		long milis = TimeUnit.NANOSECONDS.toMillis(t1 - t0);
		System.out.println(String.format("sort took: %d ms", milis));
		
		
	}

}

Map

import java.util.HashMap;
import java.util.Map;

public class MapDemo {

	public static void main(String[] args) {
		Map<Integer, String> map = new HashMap<>();
		
		for (int i=0; i<10; i++) {
			map.putIfAbsent(i, "val"+i);
		}
		
		map.forEach((id, val) -> System.out.println(val));
		
		map.computeIfPresent(3, (num, val) -> val + num);
		System.out.println(map.get(3));
		
		map.computeIfPresent(9, (num, val) -> null);
		System.out.println(map.containsKey(9));
		
		map.computeIfAbsent(23, num -> "val"+num);
		System.out.println(map.containsKey(23));
		System.out.println(map.get(23));
		
		map.computeIfAbsent(3, num -> "bam");
		System.out.println(map.get(3));
		
		map.remove(3, "val3");
		System.out.println(map.get(3));
		
		map.remove(3, "val33");
		System.out.println(map.get(3));
		
		System.out.println(map.getOrDefault(42, "Not Found"));
		
		System.out.println(map.get(9));
		map.merge(9, "val98", (value, newValue) ->
		value.concat(newValue));
		System.out.println(map.get(9));
		
		map.merge(9, "concat", (value, newValue) ->
		value.concat(newValue));
		System.out.println(map.get(9));
		
	}

}

九、Date API


import java.time.Clock;
import java.time.DayOfWeek;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.Month;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.Locale;

public class DateDemo {

	public static void main(String[] args) {
		// Clock 时钟
		Clock clock = Clock.systemDefaultZone();
		long milis = clock.millis();
		System.out.println("milis: " + milis);
		long oldMilis = System.currentTimeMillis();
		System.out.println("oldMilis: " + oldMilis);
		
		System.out.println("milis compare oldMilis: " + (milis == oldMilis));
		
		Instant instant = clock.instant();
		Date legacyDate = Date.from(instant);
		System.out.println("legacyDate: " + legacyDate);
		Date oldDate = new Date();
		System.out.println("oldDate: " + oldDate);
		
		System.out.println("legacyDate compare oldDate: " + oldDate.equals(legacyDate));
		
		// Timezones 时区
		System.out.println(ZoneId.getAvailableZoneIds());
		
		ZoneId zone1 = ZoneId.of("Europe/Berlin");
		ZoneId zone2 = ZoneId.of("Brazil/East");
		
		System.out.println(zone1.getRules());
		System.out.println(zone2.getRules());
		
		// LocalTime 本地时间
		LocalTime now1 = LocalTime.now(zone1);
		LocalTime now2 = LocalTime.now(zone2);
		
		System.out.println(now1.isBefore(now2));
		long hoursBetween = ChronoUnit.HOURS.between(now1, now2);
		long minutesBetween = ChronoUnit.MINUTES.between(now1, now2);
		
		System.out.println(hoursBetween);
		System.out.println(minutesBetween);
		
		LocalTime late = LocalTime.of(23, 59, 59);
		System.out.println(late);
		
		DateTimeFormatter germanFormatter = 
				DateTimeFormatter.ofLocalizedTime(FormatStyle.SHORT)
								 .withLocale(Locale.GERMAN);
		LocalTime leetTime = LocalTime.parse("13:37", germanFormatter);
		System.out.println(leetTime);
		
		// LocalDate 本地日期
		LocalDate today = LocalDate.now();
		LocalDate tomorrow = today.plus(1, ChronoUnit.DAYS);
		LocalDate yesterday = tomorrow.minusDays(2);
		System.out.println("yesterday is: " + yesterday);
		LocalDate independenceDay = LocalDate.of(2018, Month.JULY, 4);
		DayOfWeek dayOfWeek = independenceDay.getDayOfWeek();
		System.out.println(dayOfWeek);
		
		DateTimeFormatter germanFormatter2 = 
				DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM)
								 .withLocale(Locale.GERMAN);
		LocalDate xmas = LocalDate.parse("25.08.2018", germanFormatter2);
		System.out.println(xmas);
		
		// LocalDateTime 本地日期时间
		LocalDateTime localDateTime = LocalDateTime.of(2018, Month.MAY, 13, 20, 29, 28);
		DayOfWeek dayOfWeek2 = localDateTime.getDayOfWeek();
		System.out.println(dayOfWeek2); //SUNDAY
		
		Month month = localDateTime.getMonth();
		System.out.println(month); // MAY
		
		long minuteOfDay = localDateTime.getLong(ChronoField.MINUTE_OF_DAY);
		System.out.println(minuteOfDay); // 1229
		
		Instant instant2 = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
		Date legacyDate2 = Date.from(instant2);
		System.out.println(legacyDate2); // Sun May 13 20:29:28 CST 2018
		
		DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
		LocalDateTime parsed = LocalDateTime.parse("2018-05-13 08:38", formatter);
		String string = formatter.format(parsed);
		System.out.println(string); // 2018-05-13 08:38
		
		
		
		
	}

}

猜你喜欢

转载自my.oschina.net/u/3781047/blog/1811723