jdk1.8新特性应用之Iterable

  我们继续看lambda表达式的应用:

    public void urlExcuAspect(RpcController controller, Message request, RpcCallback done)
    {

        if (Util.isEmpty(request))
        {
            return;
        }

        Descriptor descriptor = request.getDescriptorForType();

        if (Util.isEmpty(descriptor))
        {
            return;
        }

        FieldDescriptor paramMapField = descriptor.findFieldByName("paramMap");

        if (Util.isEmpty(paramMapField))
        {
            return;
        }

        List<MapEntry<String, String>> paramList = (List<MapEntry<String, String>>)request.getField(paramMapField);

        Map<String, String> paramMap = new HashMap<>();

        paramList.forEach((entry) -> {
            if (Util.isNotEmpty(entry))
            {
                paramMap.put(entry.getKey(), entry.getValue());
            }
        });

        UesServiceUtils.setPublicParamToRequest(paramMap);

    }

  这里仍然是针对一个List接口实例paramList的操作,只不过lambda表达式所操作的函数是Collection的父接口Iterable的默认方法forEach,该方法入参是一个函数式接口Consumer:

/*
 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */
package java.lang;

import java.util.Iterator;
import java.util.Objects;
import java.util.Spliterator;
import java.util.Spliterators;
import java.util.function.Consumer;

/**
 * Implementing this interface allows an object to be the target of
 * the "for-each loop" statement. See
 * <strong>
 * <a href="{@docRoot}/../technotes/guides/language/foreach.html">For-each Loop</a>
 * </strong>
 *
 * @param <T> the type of elements returned by the iterator
 *
 * @since 1.5
 * @jls 14.14.2 The enhanced for statement
 */
public interface Iterable<T> {
    /**
     * Returns an iterator over elements of type {@code T}.
     *
     * @return an Iterator.
     */
    Iterator<T> iterator();

    /**
     * Performs the given action for each element of the {@code Iterable}
     * until all elements have been processed or the action throws an
     * exception.  Unless otherwise specified by the implementing class,
     * actions are performed in the order of iteration (if an iteration order
     * is specified).  Exceptions thrown by the action are relayed to the
     * caller.
     *
     * @implSpec
     * <p>The default implementation behaves as if:
     * <pre>{@code
     *     for (T t : this)
     *         action.accept(t);
     * }</pre>
     *
     * @param action The action to be performed for each element
     * @throws NullPointerException if the specified action is null
     * @since 1.8
     */
    default void forEach(Consumer<? super T> action) {
        Objects.requireNonNull(action);
        for (T t : this) {
            action.accept(t);
        }
    }

    /**
     * Creates a {@link Spliterator} over the elements described by this
     * {@code Iterable}.
     *
     * @implSpec
     * The default implementation creates an
     * <em><a href="Spliterator.html#binding">early-binding</a></em>
     * spliterator from the iterable‘s {@code Iterator}.  The spliterator
     * inherits the <em>fail-fast</em> properties of the iterable‘s iterator.
     *
     * @implNote
     * The default implementation should usually be overridden.  The
     * spliterator returned by the default implementation has poor splitting
     * capabilities, is unsized, and does not report any spliterator
     * characteristics. Implementing classes can nearly always provide a
     * better implementation.
     *
     * @return a {@code Spliterator} over the elements described by this
     * {@code Iterable}.
     * @since 1.8
     */
    default Spliterator<T> spliterator() {
        return Spliterators.spliteratorUnknownSize(iterator(), 0);
    }
}

  先看下静态方法requireNonNull:

/*
 * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */

package java.util;

import java.util.function.Supplier;

/**
 * This class consists of {@code static} utility methods for operating
 * on objects.  These utilities include {@code null}-safe or {@code
 * null}-tolerant methods for computing the hash code of an object,
 * returning a string for an object, and comparing two objects.
 *
 * @since 1.7
 */
public final class Objects {
    private Objects() {
        throw new AssertionError("No java.util.Objects instances for you!");
    }

    /**
     * Returns {@code true} if the arguments are equal to each other
     * and {@code false} otherwise.
     * Consequently, if both arguments are {@code null}, {@code true}
     * is returned and if exactly one argument is {@code null}, {@code
     * false} is returned.  Otherwise, equality is determined by using
     * the {@link Object#equals equals} method of the first
     * argument.
     *
     * @param a an object
     * @param b an object to be compared with {@code a} for equality
     * @return {@code true} if the arguments are equal to each other
     * and {@code false} otherwise
     * @see Object#equals(Object)
     */
    public static boolean equals(Object a, Object b) {
        return (a == b) || (a != null && a.equals(b));
    }

   /**
    * Returns {@code true} if the arguments are deeply equal to each other
    * and {@code false} otherwise.
    *
    * Two {@code null} values are deeply equal.  If both arguments are
    * arrays, the algorithm in {@link Arrays#deepEquals(Object[],
    * Object[]) Arrays.deepEquals} is used to determine equality.
    * Otherwise, equality is determined by using the {@link
    * Object#equals equals} method of the first argument.
    *
    * @param a an object
    * @param b an object to be compared with {@code a} for deep equality
    * @return {@code true} if the arguments are deeply equal to each other
    * and {@code false} otherwise
    * @see Arrays#deepEquals(Object[], Object[])
    * @see Objects#equals(Object, Object)
    */
    public static boolean deepEquals(Object a, Object b) {
        if (a == b)
            return true;
        else if (a == null || b == null)
            return false;
        else
            return Arrays.deepEquals0(a, b);
    }

    /**
     * Returns the hash code of a non-{@code null} argument and 0 for
     * a {@code null} argument.
     *
     * @param o an object
     * @return the hash code of a non-{@code null} argument and 0 for
     * a {@code null} argument
     * @see Object#hashCode
     */
    public static int hashCode(Object o) {
        return o != null ? o.hashCode() : 0;
    }

   /**
    * Generates a hash code for a sequence of input values. The hash
    * code is generated as if all the input values were placed into an
    * array, and that array were hashed by calling {@link
    * Arrays#hashCode(Object[])}.
    *
    * <p>This method is useful for implementing {@link
    * Object#hashCode()} on objects containing multiple fields. For
    * example, if an object that has three fields, {@code x}, {@code
    * y}, and {@code z}, one could write:
    *
    * <blockquote><pre>
    * @Override public int hashCode() {
    *     return Objects.hash(x, y, z);
    * }
    * </pre></blockquote>
    *
    * <b>Warning: When a single object reference is supplied, the returned
    * value does not equal the hash code of that object reference.</b> This
    * value can be computed by calling {@link #hashCode(Object)}.
    *
    * @param values the values to be hashed
    * @return a hash value of the sequence of input values
    * @see Arrays#hashCode(Object[])
    * @see List#hashCode
    */
    public static int hash(Object... values) {
        return Arrays.hashCode(values);
    }

    /**
     * Returns the result of calling {@code toString} for a non-{@code
     * null} argument and {@code "null"} for a {@code null} argument.
     *
     * @param o an object
     * @return the result of calling {@code toString} for a non-{@code
     * null} argument and {@code "null"} for a {@code null} argument
     * @see Object#toString
     * @see String#valueOf(Object)
     */
    public static String toString(Object o) {
        return String.valueOf(o);
    }

    /**
     * Returns the result of calling {@code toString} on the first
     * argument if the first argument is not {@code null} and returns
     * the second argument otherwise.
     *
     * @param o an object
     * @param nullDefault string to return if the first argument is
     *        {@code null}
     * @return the result of calling {@code toString} on the first
     * argument if it is not {@code null} and the second argument
     * otherwise.
     * @see Objects#toString(Object)
     */
    public static String toString(Object o, String nullDefault) {
        return (o != null) ? o.toString() : nullDefault;
    }

    /**
     * Returns 0 if the arguments are identical and {@code
     * c.compare(a, b)} otherwise.
     * Consequently, if both arguments are {@code null} 0
     * is returned.
     *
     * <p>Note that if one of the arguments is {@code null}, a {@code
     * NullPointerException} may or may not be thrown depending on
     * what ordering policy, if any, the {@link Comparator Comparator}
     * chooses to have for {@code null} values.
     *
     * @param <T> the type of the objects being compared
     * @param a an object
     * @param b an object to be compared with {@code a}
     * @param c the {@code Comparator} to compare the first two arguments
     * @return 0 if the arguments are identical and {@code
     * c.compare(a, b)} otherwise.
     * @see Comparable
     * @see Comparator
     */
    public static <T> int compare(T a, T b, Comparator<? super T> c) {
        return (a == b) ? 0 :  c.compare(a, b);
    }

    /**
     * Checks that the specified object reference is not {@code null}. This
     * method is designed primarily for doing parameter validation in methods
     * and constructors, as demonstrated below:
     * <blockquote><pre>
     * public Foo(Bar bar) {
     *     this.bar = Objects.requireNonNull(bar);
     * }
     * </pre></blockquote>
     *
     * @param obj the object reference to check for nullity
     * @param <T> the type of the reference
     * @return {@code obj} if not {@code null}
     * @throws NullPointerException if {@code obj} is {@code null}
     */
    public static <T> T requireNonNull(T obj) {
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }

    /**
     * Checks that the specified object reference is not {@code null} and
     * throws a customized {@link NullPointerException} if it is. This method
     * is designed primarily for doing parameter validation in methods and
     * constructors with multiple parameters, as demonstrated below:
     * <blockquote><pre>
     * public Foo(Bar bar, Baz baz) {
     *     this.bar = Objects.requireNonNull(bar, "bar must not be null");
     *     this.baz = Objects.requireNonNull(baz, "baz must not be null");
     * }
     * </pre></blockquote>
     *
     * @param obj     the object reference to check for nullity
     * @param message detail message to be used in the event that a {@code
     *                NullPointerException} is thrown
     * @param <T> the type of the reference
     * @return {@code obj} if not {@code null}
     * @throws NullPointerException if {@code obj} is {@code null}
     */
    public static <T> T requireNonNull(T obj, String message) {
        if (obj == null)
            throw new NullPointerException(message);
        return obj;
    }

    /**
     * Returns {@code true} if the provided reference is {@code null} otherwise
     * returns {@code false}.
     *
     * @apiNote This method exists to be used as a
     * {@link java.util.function.Predicate}, {@code filter(Objects::isNull)}
     *
     * @param obj a reference to be checked against {@code null}
     * @return {@code true} if the provided reference is {@code null} otherwise
     * {@code false}
     *
     * @see java.util.function.Predicate
     * @since 1.8
     */
    public static boolean isNull(Object obj) {
        return obj == null;
    }

    /**
     * Returns {@code true} if the provided reference is non-{@code null}
     * otherwise returns {@code false}.
     *
     * @apiNote This method exists to be used as a
     * {@link java.util.function.Predicate}, {@code filter(Objects::nonNull)}
     *
     * @param obj a reference to be checked against {@code null}
     * @return {@code true} if the provided reference is non-{@code null}
     * otherwise {@code false}
     *
     * @see java.util.function.Predicate
     * @since 1.8
     */
    public static boolean nonNull(Object obj) {
        return obj != null;
    }

    /**
     * Checks that the specified object reference is not {@code null} and
     * throws a customized {@link NullPointerException} if it is.
     *
     * <p>Unlike the method {@link #requireNonNull(Object, String)},
     * this method allows creation of the message to be deferred until
     * after the null check is made. While this may confer a
     * performance advantage in the non-null case, when deciding to
     * call this method care should be taken that the costs of
     * creating the message supplier are less than the cost of just
     * creating the string message directly.
     *
     * @param obj     the object reference to check for nullity
     * @param messageSupplier supplier of the detail message to be
     * used in the event that a {@code NullPointerException} is thrown
     * @param <T> the type of the reference
     * @return {@code obj} if not {@code null}
     * @throws NullPointerException if {@code obj} is {@code null}
     * @since 1.8
     */
    public static <T> T requireNonNull(T obj, Supplier<String> messageSupplier) {
        if (obj == null)
            throw new NullPointerException(messageSupplier.get());
        return obj;
    }
}

  再重点看Consumer接口:

/*
 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
 * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 *
 */
package java.util.function;

import java.util.Objects;

/**
 * Represents an operation that accepts a single input argument and returns no
 * result. Unlike most other functional interfaces, {@code Consumer} is expected
 * to operate via side-effects.
 *
 * <p>This is a <a href="package-summary.html">functional interface</a>
 * whose functional method is {@link #accept(Object)}.
 *
 * @param <T> the type of the input to the operation
 *
 * @since 1.8
 */
@FunctionalInterface
public interface Consumer<T> {

    /**
     * Performs this operation on the given argument.
     *
     * @param t the input argument
     */
    void accept(T t);

    /**
     * Returns a composed {@code Consumer} that performs, in sequence, this
     * operation followed by the {@code after} operation. If performing either
     * operation throws an exception, it is relayed to the caller of the
     * composed operation.  If performing this operation throws an exception,
     * the {@code after} operation will not be performed.
     *
     * @param after the operation to perform after this operation
     * @return a composed {@code Consumer} that performs in sequence this
     * operation followed by the {@code after} operation
     * @throws NullPointerException if {@code after} is null
     */
    default Consumer<T> andThen(Consumer<? super T> after) {
        Objects.requireNonNull(after);
        return (T t) -> { accept(t); after.accept(t); };
    }
}

  抽象方法accept接收一个对象,然后操作该对象,无需返回任何类型。很简单吧,拿Predicate的test对比一下,test做的是判断,accept做的是操作。举个例子:

        Consumer<String> consumer = (s) -> System.out.println("Hello, " + s.toUpperCase());
        consumer.accept("wlf");

  这个consumer实例做的就是打印"Hello,wlf"这个操作。再回过来看我们最开始的代码:

        paramList.forEach((entry) -> {
            if (Util.isNotEmpty(entry))
            {
                paramMap.put(entry.getKey(), entry.getValue());
            }
        });

  遍历paramList,从每个MapEntry<String, String>对象中取出key和value,放到paramMap对象中。好了,我们继续看:

        List<String> list = new ArrayList<String>();
        list.add("wlf");
        list.add("wms");
        list.stream().filter((s) -> s.startsWith("w")).forEach(System.out::println);

  最后一行融合之前所有jdk1.8新特性,从List父接口Collection的stream默认方法取得一个Stream,通过Stream的filter进行中间操作(这里的操作就是Predicate的test,判断是否w开头),最后通过List祖父接口Iterable的forEach方法进行最终操作(这里的操作就是Consumer的accept,打印最终list对象)。

原文地址:https://www.cnblogs.com/wuxun1997/p/9117822.html

时间: 2024-11-29 06:02:30

jdk1.8新特性应用之Iterable的相关文章

59. jdk1.5新特性之----增强for循环

/*jdk1.5新特性之----增强for循环:底层是一个迭代器 作用:简化迭代器书写格式 使用范围:实现了Iterable接口的对象或者数组对象 格式:    for(变量类型  变量名 :遍历目标){        //代码块    }    注意:    1.因为for in循环底层还是迭代器,所以在循环的时候我们不能修改迭代对象的长度    2.因为我们没有实例化迭代器对象,所以我们不能使用迭代器中的一些方法*/ 基本运用实例代码: public class Demo2 { public

jdk1.5新特性和jdk1.7新特性

jdk1.5新特性 1.自动装箱和自动拆箱 自动装箱,把基本类型的值变成对象类型 Integer a = 2; 自动拆箱,把对象类型变成基本类型 int b = new Integer(2); 而不需要调用intValue int b = new Integer(2).intValue(); 包装类有 Integer Boolean Float Double Short Byte 2.枚举 java枚举具有简单和安全性. 3.泛型 泛型在编译的时候可以控制类型,比如说List<String>

黑马程序员——java高新---JDK1.5新特性和反射

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 一.JDK1.5新特性 ——>静态导入 import和import static之间的区别: 1.import是导入一个类或某个包中所有的类. 2.import static是导入一个类中的某个静态成员或所有的静态成员. 注意: 1.当导入的两个类中有同名成员时,需要在成员前加上相应的类名. 2.当类名重名时,需要指定具体的包名. 3.方法重名时,需要指定具体所属的对象或者类. 代码示例: 1

接口、接口优点、接口的属性和方法特性、接口与继承的区别、接口与抽象类的区别、匿名实现类、JDK1.8新特性、打印类名称

接口里的属性,必须是公共的/默认的&静态的&Final&初始化后的属性: 接口里所有方法都是抽象的. 接口和继承---先天有的用继承,后天学习的用接口: 接口特性-------- 1.接口不可以被实例化: 2.实现类必须实现接口中所有方法,否则实现类必须是抽象类 3.实现类可以实现多个接口,来弥补Java不能多继承: 4.接口中的变量都是静态常量:(静态的-可以通过类的名字点-直接调用:) ----------------------------------------------

jdk1.5新特性

package cn.itcast.jdk15; import java.util.ArrayList; /* jdk1.5新特性之-----自动装箱与自动拆箱. java是面向对象 的语言,任何事物都可以使用类进行描述,sun就使用了 一些类描述java中八种基本数据类型数据 基本数据类型 包装类型 byte Byte short Short int Integer long Long float Float double Double boolean Boolean char Charact

黑马程序员------Java中jdk1.5新特性

Java培训.Android培训.iOS培训..Net培训.期待与您交流! JDK1.5新特性: 为什么会出现新特性: 新的技术出现是为了解决老的问题,Java语言为了提高开发者的开发效率,对之前的某些不利于提高效率的技术进行改进. 静态导入: 静态导入:可以导入某个类下的静态方法,静态导入后,可以不写类名而直接使用此类下的静态方法. 语法:import static 包名.类名.静态方法 代码示例: package com.itheima.day1; /** * 静态导入 * @author

jdk1.5新特性之-------&gt;可变参数

/* jdk1.5新特性之------->可变参数 需求: 定义一个函数做加法功能(函数做几个数据 的加法功能是不确定). 可变参数的格式: 数据类型... 变量名 可变参数要 注意的细节: 1. 如果一个函数 的形参使用上了可变参数之后,那么调用该方法的时候可以传递参数也可以不传递参数. 2. 可变参数实际上是一个数组对象. 3. 可变参数必须位于形参中的最后一个参数. 4. 一个函数最多只能有一个可变 参数,因为可变参数要位于形参中最后一个位置上. */ public class Demo4

jdk1.8新特性之lambda表达式

lambda表达式其实就是指一个匿名函数,应用最广泛的就是匿名内部类.在jdk1.8之前,我们定义一个匿名内部类可能需要写一大坨代码,现在有了lambda之后,可以写的很简洁了.但不是说lambda只能用来简化匿名内部类,从lambda的实际作用和表现上来看,就是一个变量指代一个代码块.而能够使用lambda表达式的一个前提要求是,该变量必须实现某个函数式接口.啥是函数式接口?参考jdk1.8新特性之函数式接口.看例子: 1.函数式接口 * Copyright (c) 1994, 2013, O

JDK1.8新特性(二): Lambda表达式 (参数列表) -&gt; { } 和函数式接口@FunctionalInterface

Lambda表达式 二:简介 JDK的升级的目的有以下几个:增加新的功能.修复bug.性能优化.简化代码等几个方面,Lambda表达式就是属于简化代码,用于简化匿名实现类,提供一种更加简洁的写法.Lambda表达式在Swift语言中称之为代码块,Lambda表达式可以认为是一种特殊的接口,该接口必须只有一个抽象方法. 语法 (参数类型 参数名, 数参数类型 参数名2...) -> { // code }; 小括号()中的内容就是方法中的参数列表包括参数类型.参数名,其中参数类型是可以省略的,当参