1.default :实现面向接口编程
以前在使用java编程的时候,如果想复用某些特定实现方法,似乎只有通过继承或者委托来实现,但是由于java中又只能单继承,如果使用继承就会导致难以扩展,使用委托有会导致某些本应是继承关系的类变得模糊。
2. Lambda 表达式 让你的代码更加简洁
比如在此之前写一个排序方法:
通过使用Lambda 表达式(->)之后就可以极大的简化代码了
首先需要定义一抽象类型的接口方法,例如jdk的自带实现
注:上述代码只是截取的了该方法中的一部分
这样我们就可以通过Lambda 表达式来简化我们的代码,如下:
解释:
(a,b)->a.compareTo(b)
其中 -> 表达式的左边为输入参数 右边为返回值
@FunctionInterface:如果发现该接口有多于一个抽象方法就会报错,用于让编译器帮助你语法检查。不带也没有问题。
3.方法的引用(::表达式):让你的代码更加灵活
例子:
首先定义一个测试对象,待会来引用该对象的方法
a.对静态方法的引用
a1.首先定义一个函数接口
c.对构造方法的引用
c1.编写函数接口
c2.编写测试类
a.Function
有一个参数并返回一个结果,同时实现了可以和其他函数组合的默认方法,定义如下:
b.supplier
和Function接口区别不大,返回一个任意泛型的值,和Function接口的区别在于其方法接口没有参数输入,也就是0输入,1输出
定义
c.Consumer
顾名思义,也就是消费的意思
定义
例子
d.stream
定义:由于这个接口功能比较强大,同时代码比较长,有兴趣的可以在JDK中查看定义,此接口增强了集合类的操作,同时也可以让代码更加简洁
d1.filter方法
定义
d2.sorted方法
该方法有两个定义如下:
例子:
d3.map
方法的定义
例子:将字符串转化为大写
d4:match方法
定义
作用:检测指定的predicate是否匹配整个stream
anyMatch:只有stream中任意一个元素匹配就返回true
allMatch:只有stream中所有元素匹配才返回true
noneMatch:只有stream中没有一个匹配才返回true
d5:Count
用于返回stream中的元素数量,当然可以和filter一起使用
定义
作用:用于将stream中的某些元素通过指定的规则合并成一个
定义
例子:
作用:并行处理的parallelStream,在某种情形下处理速度会大大高于stram,但是并非一定会快。
定义
5.Map的增强操作
Map不支持stream,同时也定义了一些好用的特性
a.putIfAbsent
定义:
作用:通过上述代码就可以,就可以很清楚的表明了其作用,也就是插入数据的时候不需要做存在性检测
b.computeIfPresent
定义:
c.remove
定义
例子:
d.getOrDefault
定义:
e.merge
定义
例子:
以前在使用java编程的时候,如果想复用某些特定实现方法,似乎只有通过继承或者委托来实现,但是由于java中又只能单继承,如果使用继承就会导致难以扩展,使用委托有会导致某些本应是继承关系的类变得模糊。
现在可以在接口中通过 default 关键字 就可以在接口中完成方法的实现了。
例子:
public interface TestDefault {
public int getSum();
default String getDescribe(){
return "Default description";
}
}
这样就可以愉快的使用面向接口编程了。
2. Lambda 表达式 让你的代码更加简洁
比如在此之前写一个排序方法:
@Test
public void testSort(){
List<Integer> needSortNum = Arrays.asList(1,3,9,0,2,5,7);
Collections.sort(needSortNum, new Comparator<Integer>() {
@Override
public int compare(Integer a, Integer b) {
return b.compareTo(a);
}
});
System.out.println(needSortNum);
}
通过使用Lambda 表达式(->)之后就可以极大的简化代码了
首先需要定义一抽象类型的接口方法,例如jdk的自带实现
@FunctionalInterface
public interface Comparator<T> {
int compare(T o1, T o2);
}
注:上述代码只是截取的了该方法中的一部分
这样我们就可以通过Lambda 表达式来简化我们的代码,如下:
@Test
public void testSort(){
List<Integer> needSortNum = Arrays.asList(1,3,9,0,2,5,7);
Collections.sort(needSortNum,(a,b)->a.compareTo(b));
System.out.println(needSortNum);
}
解释:
(a,b)->a.compareTo(b)
其中 -> 表达式的左边为输入参数 右边为返回值
@FunctionInterface:如果发现该接口有多于一个抽象方法就会报错,用于让编译器帮助你语法检查。不带也没有问题。
3.方法的引用(::表达式):让你的代码更加灵活
例子:
首先定义一个测试对象,待会来引用该对象的方法
public class FunctionQuote {
private Integer money;
public FunctionQuote(){}
public FunctionQuote(int money){
this.money=money;
}
public void print(){
System.out.println("routine function");
}
public static void staticPrint(){
System.out.println("static function");
}
}
a.对静态方法的引用
a1.首先定义一个函数接口
@FunctionalInterface
public interface FunctionInterface {
void print();
}
a2.编写测试类
public class TestFunctionQuote {
@Test
public void testQuote(){
FunctionInterface functionInterface=FunctionQuote::staticPrint;
functionInterface.print();
}
}
b.对非静态方法的引用
public class TestFunctionQuote {
@Test
public void testQuote(){
FunctionQuote functionQuote=new FunctionQuote();
FunctionInterface functionInterface=functionQuote::print;
functionInterface.print();
}
}
c.对构造方法的引用
c1.编写函数接口
@FunctionalInterface
public interface CFunctionInterface<T>{
T createObj();
}
c2.编写测试类
@Test
public void testQuote(){
CFunctionInterface<FunctionQuote> factory = FunctionQuote::new;
FunctionQuote obj=factory.createObj();
}
4.访问接口的默认方法
a.Function
有一个参数并返回一个结果,同时实现了可以和其他函数组合的默认方法,定义如下:
@FunctionalInterface
public interface Function<T, R> {
R apply(T t);
default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
Objects.requireNonNull(before);
return (V v) -> apply(before.apply(v));
}
default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
Objects.requireNonNull(after);
return (T t) -> after.apply(apply(t));
}
static <T> Function<T, T> identity() {
return t -> t;
}
}
用法例子:
public class TestFunction {
@Test
public void testQuote(){
Function<String,String> printStr1=this::firstPrint;
Function<String,String> printStr2=printStr1.andThen(this::secondPrint);
printStr1.apply("hello world111");
System.out.println("--------------------------");
printStr2.apply("hello world222");
}
public String firstPrint(String s){
System.out.println(s+" fisrt print");
return s;
}
public String secondPrint(String s){
System.out.println(s+" second print");
return s;
}
}
b.supplier
和Function接口区别不大,返回一个任意泛型的值,和Function接口的区别在于其方法接口没有参数输入,也就是0输入,1输出
定义
@FunctionalInterface
public interface Supplier<T> {
T get();
}
例子
public class TestSupplier {
@Test
public void testQuote(){
Supplier<Integer> supplier=this::getMoney;
System.out.println(supplier.get());
}
public int getMoney(){
return 10000000;
}
}
c.Consumer
顾名思义,也就是消费的意思
定义
@FunctionalInterface
public interface Consumer<T> {
void accept(T t);
default Consumer<T> andThen(Consumer<? super T> after) {
Objects.requireNonNull(after);
return (T t) -> { accept(t); after.accept(t); };
}
}
例子
@Test
public void testQuote(){
Consumer<Integer> consumer1=(p) -> System.out.println("first:"+p);
Consumer<Integer> consumer2=consumer1.andThen((p)->System.out.println("second:"+p));
consumer1.accept(1);
System.out.println("--------------------");
consumer2.accept(2);
}
d.stream
定义:由于这个接口功能比较强大,同时代码比较长,有兴趣的可以在JDK中查看定义,此接口增强了集合类的操作,同时也可以让代码更加简洁
d1.filter方法
定义
Stream<T> filter(Predicate<? super T> predicate);
例子
public class TestSupplier {
@Test
public void testQuote(){
List<String> testList=createTestObj();
testList.stream().filter((str)->str.contains("123")).forEach(this::print);
}
private List<String> createTestObj(){
return Arrays.asList("a1234","b123","c1234","d123","e1234","f123","g123");
}
private void print(String str){
System.out.print(str+" ");
}
}
d2.sorted方法
该方法有两个定义如下:
Stream<T> sorted();
Stream<T> sorted(Comparator<? super T> comparator);
如果使用sorted()则使用默认的排序规则,或者传入一个指定的规则
例子:
public class TestSupplier {
@Test
public void testQuote(){
List<String> testList=createTestObj();
testList.stream().sorted((a,b)->b.compareTo(a)).forEach(this::print);
}
private List<String> createTestObj(){
return Arrays.asList("a1234","b123","c1234","d123","e1234","f123","g123");
}
private void print(String str){
System.out.print(str+" ");
}
}
d3.map
方法的定义
<R> Stream<R> map(Function<? super T, ? extends R> mapper);
作用:根据指定的Function接口将集合中的元素转换成另一种形式
例子:将字符串转化为大写
public class TestSupplier {
@Test
public void testQuote(){
List<String> testList=createTestObj();
testList.stream().sorted((a,b)->b.compareTo(a)).map(String::toUpperCase).forEach(this::print);
}
private List<String> createTestObj(){
return Arrays.asList("a1234","b123","c1234","d123","e1234","f123","g123");
}
private void print(String str){
System.out.print(str+" ");
}
}
d4:match方法
定义
boolean anyMatch(Predicate<? super T> predicate);
boolean allMatch(Predicate<? super T> predicate);
boolean noneMatch(Predicate<? super T> predicate);
作用:检测指定的predicate是否匹配整个stream
anyMatch:只有stream中任意一个元素匹配就返回true
allMatch:只有stream中所有元素匹配才返回true
noneMatch:只有stream中没有一个匹配才返回true
@Test
public void testQuote(){
List<String> testList=createTestObj();
boolean anyStartsWithA = testList.stream().anyMatch((s) -> s.startsWith("a")); //true
boolean allStartsWithA = testList.stream().allMatch((s) -> s.startsWith("a")); //false
boolean noneStartsWithA = testList.stream().noneMatch((s) -> s.startsWith("a")); //false
}
private List<String> createTestObj(){
return Arrays.asList("a1234","b123","c1234","d123","e1234","f123","g123");
}
d5:Count
用于返回stream中的元素数量,当然可以和filter一起使用
定义
long count();
例子
@Test
public void testQuote(){
List<String> testList=createTestObj();
testList.stream().count();
testList.stream().filter((s)->s.startsWith("a"));
}
private List<String> createTestObj(){
return Arrays.asList("a1234","b123","c1234","d123","e1234","f123","g123");
}
d6:Reduce
作用:用于将stream中的某些元素通过指定的规则合并成一个
定义
T reduce(T identity, BinaryOperator<T> accumulator);
Optional<T> reduce(BinaryOperator<T> accumulator);
<U> U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator<U> combiner);
例子:
@Test
public void testQuote(){
List<String> testList=createTestObj();
Optional<String> reduced=testList.stream().reduce((a,b)-> a+"#"+b);
System.out.println(reduced.get());
}
private List<String> createTestObj(){
return Arrays.asList("a1234","b123","c1234","d123","e1234","f123","g123");
}
e:parallelStream
作用:并行处理的parallelStream,在某种情形下处理速度会大大高于stram,但是并非一定会快。
定义
default Stream<E> parallelStream() {
return StreamSupport.stream(spliterator(), true);
}
5.Map的增强操作
Map不支持stream,同时也定义了一些好用的特性
a.putIfAbsent
定义:
default V putIfAbsent(K key, V value) {
V v = get(key);
if (v == null) {
v = put(key, value);
}
return v;
}
作用:通过上述代码就可以,就可以很清楚的表明了其作用,也就是插入数据的时候不需要做存在性检测
b.computeIfPresent
定义:
default V computeIfPresent(K key,
BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
V oldValue;
if ((oldValue = get(key)) != null) {
V newValue = remappingFunction.apply(key, oldValue);
if (newValue != null) {
put(key, newValue);
return newValue;
} else {
remove(key);
return null;
}
} else {
return null;
}
}
作用:修改特定key对应的value值,该值的修改通过传入的key value共同决定
@Test
public void testQuote(){
Map<Integer, String> map = new HashMap<>();
for (int i = 0; i < 10; i++) {
map.putIfAbsent(i, "val" + i);
}
System.out.println(map.get(3)); // val3
map.computeIfPresent(3, (key, val) -> val + key);
System.out.println(map.get(3)); // val33
}
c.remove
定义
V remove(Object key);
例子:
default boolean remove(Object key, Object value) {
Object curValue = get(key);
if (!Objects.equals(curValue, value) ||
(curValue == null && !containsKey(key))) {
return false;
}
remove(key);
return true;
}
d.getOrDefault
定义:
default V getOrDefault(Object key, V defaultValue) {
V v;
return (((v = get(key)) != null) || containsKey(key))
? v
: defaultValue;
}
e.merge
定义
default V merge(K key, V value,
BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
Objects.requireNonNull(remappingFunction);
Objects.requireNonNull(value);
V oldValue = get(key);
V newValue = (oldValue == null) ? value :
remappingFunction.apply(oldValue, value);
if(newValue == null) {
remove(key);
} else {
put(key, newValue);
}
return newValue;
}
作用:针对特定的key对value进行操作
例子:
@Test
public void testQuote(){
Map<Integer, String> map = new HashMap<>();
for (int i = 0; i < 10; i++) {
map.putIfAbsent(i, "val" + i);
}
map.get(9); //val
map.merge(9, "addval", (value, addValue) -> value+addValue);
map.get(9); //val9addval
}