zoukankan      html  css  js  c++  java
  • jdk1.8新特性应用之Collection

      之前说了jdk1.8几个新特性,现在看下实战怎么玩,直接看代码:

        public List<MSG_ConMediaInfo> getConMediaInfoList(String liveType)
        {
            if (Util.isEmpty(liveType))
            {
                return null;
            }
            List<MSG_ConMediaInfo> conMediaInfoList = getConMediaInfoList();
            if (Util.isNotEmpty(conMediaInfoList))
            {
                if (LIVE_TYPE_BEING.equals(liveType))
                {
                    return conMediaInfoList.parallelStream()
                        .filter(s -> s != null)
                        .filter(s -> isLiveBeing(s))
                        .collect(Collectors.toList());
                }
                else if (LIVE_TYPE_PREVIEW.equals(liveType))
                {
                    return conMediaInfoList.parallelStream()
                        .filter(s -> s != null)
                        .filter(s -> isLivePreview(s))
                        .collect(Collectors.toList());
                }
                else
                {
                    return conMediaInfoList.parallelStream()
                        .filter(s -> s != null)
                        .filter(s -> liveType.equals(s.getLiveStatus()))
                        .collect(Collectors.toList());
                }
            }
            return null;
        }
    
    
        private boolean isLiveBeing(MSG_ConMediaInfo conMediaInfo)
        {
            String liveStatus = conMediaInfo.getLiveStatus();
            if (LIVE_TYPE_BEING.equals(liveStatus))
            {
                return Boolean.TRUE;
            }
            if (LIVE_TYPE_PREVIEW.equals(liveStatus))
            {
                if (!isLivePreview(conMediaInfo))
                {
                    return Boolean.TRUE;
                }
            }
            return Boolean.FALSE;
        }
    
    
        private boolean isLivePreview(MSG_ConMediaInfo conMediaInfo)
        {
            if (LIVE_TYPE_PREVIEW.equals(conMediaInfo.getLiveStatus()))
            {
                String startTime =
                    DateTools.timeTransform(conMediaInfo.getLiveStartTime(),
                        DateTools.DATE_PATTERN_24HOUR_16);
                int result =
                    DateTools.compare(new Date(), DateTools.timeStr2Date(startTime, DateTools.DATE_PATTERN_24HOUR_16),
                        CompareDateFormate.yyyyMMddhhmmss);
                //当前时间已超过直播开始时间
                if (result != -1)
                {
                    return Boolean.FALSE;
                }
                return Boolean.TRUE;
            }
            return Boolean.FALSE;
        }

      这里3个方法,第一个方法使用了lambda表达式,这里是一个List实例conMediaInfoList,通过调用parallelStream方法得到一个Stream接口,再调用它的filter方法,该方法的参数是一个函数式接口Predicate。步步推进,终于绕到函数式接口这个jdk1.8的新特性了。我们知道,lambda表达式使用的前提就是函数式接口。

      那么首先让我们来看下Predicate:

     * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
    package java.util.function;
    
    import java.util.Objects;
    
    /**
     * Represents a predicate (boolean-valued function) of one argument.
     *
     * <p>This is a <a href="package-summary.html">functional interface</a>
     * whose functional method is {@link #test(Object)}.
     *
     * @param <T> the type of the input to the predicate
     *
     * @since 1.8
     */
    @FunctionalInterface
    public interface Predicate<T> {
    
        /**
         * Evaluates this predicate on the given argument.
         *
         * @param t the input argument
         * @return {@code true} if the input argument matches the predicate,
         * otherwise {@code false}
         */
        boolean test(T t);
    
        /**
         * Returns a composed predicate that represents a short-circuiting logical
         * AND of this predicate and another.  When evaluating the composed
         * predicate, if this predicate is {@code false}, then the {@code other}
         * predicate is not evaluated.
         *
         * <p>Any exceptions thrown during evaluation of either predicate are relayed
         * to the caller; if evaluation of this predicate throws an exception, the
         * {@code other} predicate will not be evaluated.
         *
         * @param other a predicate that will be logically-ANDed with this
         *              predicate
         * @return a composed predicate that represents the short-circuiting logical
         * AND of this predicate and the {@code other} predicate
         * @throws NullPointerException if other is null
         */
        default Predicate<T> and(Predicate<? super T> other) {
            Objects.requireNonNull(other);
            return (t) -> test(t) && other.test(t);
        }
    
        /**
         * Returns a predicate that represents the logical negation of this
         * predicate.
         *
         * @return a predicate that represents the logical negation of this
         * predicate
         */
        default Predicate<T> negate() {
            return (t) -> !test(t);
        }
    
        /**
         * Returns a composed predicate that represents a short-circuiting logical
         * OR of this predicate and another.  When evaluating the composed
         * predicate, if this predicate is {@code true}, then the {@code other}
         * predicate is not evaluated.
         *
         * <p>Any exceptions thrown during evaluation of either predicate are relayed
         * to the caller; if evaluation of this predicate throws an exception, the
         * {@code other} predicate will not be evaluated.
         *
         * @param other a predicate that will be logically-ORed with this
         *              predicate
         * @return a composed predicate that represents the short-circuiting logical
         * OR of this predicate and the {@code other} predicate
         * @throws NullPointerException if other is null
         */
        default Predicate<T> or(Predicate<? super T> other) {
            Objects.requireNonNull(other);
            return (t) -> test(t) || other.test(t);
        }
    
        /**
         * Returns a predicate that tests if two arguments are equal according
         * to {@link Objects#equals(Object, Object)}.
         *
         * @param <T> the type of arguments to the predicate
         * @param targetRef the object reference with which to compare for equality,
         *               which may be {@code null}
         * @return a predicate that tests if two arguments are equal according
         * to {@link Objects#equals(Object, Object)}
         */
        static <T> Predicate<T> isEqual(Object targetRef) {
            return (null == targetRef)
                    ? Objects::isNull
                    : object -> targetRef.equals(object);
        }
    }

      我们看到该接口只有一个抽象方法(只能有一个,否则就不能叫函数式接口),3个默认方法和一个静态方法。该接口只有一个参数t,返回一个布尔值。我们先看看能怎么用这个接口:

                // Predicate接口实例predicate指代一段判断字符串s是否长度大于0的代码
                Predicate<String> predicate = (s) -> s.length() > 0; 
                
                // predicate应用,判断字符串wlf是否长度>0
                predicate.test("wlf");
                
                // predicate应用,判断字符串wlf是否长度<=0
                predicate.negate().test("wlf"); 
                
                // 方法引用:Objects.isNull返回一个boolean,
                Predicate<Object> isNull = Objects::isNull;
                
                // 方法引用:String.isEmpty方法一个boolean
                Predicate<String> isEmpty = String::isEmpty;

      Predicate接口做的事情就是判断参数s是否符合方法体里的判断逻辑,而方法体的逻辑是由你自己实现的。上面分别判断了一个字符串的长度大于0、不大于0,对象是否为空,字符串是否为空。

      我们溯流而上,接下来再看下Stream的filter方法

    public interface Stream<T> extends BaseStream<T, Stream<T>> {
    
        /**
         * Returns a stream consisting of the elements of this stream that match
         * the given predicate.
         *
         * <p>This is an <a href="package-summary.html#StreamOps">intermediate
         * operation</a>.
         *
         * @param predicate a <a href="package-summary.html#NonInterference">non-interfering</a>,
         *                  <a href="package-summary.html#Statelessness">stateless</a>
         *                  predicate to apply to each element to determine if it
         *                  should be included
         * @return the new stream
         */
        Stream<T> filter(Predicate<? super T> predicate);
    }

      这个方法就是执行Predicate的判断逻辑,通过再返回一个Stream。再回过来看最开始的代码:

    conMediaInfoList.parallelStream()
                        .filter(s -> s != null)
                        .filter(s -> isLiveBeing(s))
                        .collect(Collectors.toList());

      我们看到lambda表达式里先判断MSG_ConMediaInfo实例是否不为null,再判断实例是否符合isLiveBeing方法里的判断逻辑,两个都返回true的话,继续调用collect方法返回一个List。

      接下来聊下Stream接口。它表示在一组元素上一次执行的操作序列,包括中间操作或者最终操作,中间操作继续返回Stream,直到操作序列结束,执行最终操作。像上面的业务代码,filter是中间操作,collect是最终操作。那么Stream怎么创建呢?只能通过容器类来创建,有两个方法都可以返回Stream:

    public interface Collection<E> extends Iterable<E> {

     /**
         * Returns a sequential {@code Stream} with this collection as its source.
         *
         * <p>This method should be overridden when the {@link #spliterator()}
         * method cannot return a spliterator that is {@code IMMUTABLE},
         * {@code CONCURRENT}, or <em>late-binding</em>. (See {@link #spliterator()}
         * for details.)
         *
         * @implSpec
         * The default implementation creates a sequential {@code Stream} from the
         * collection's {@code Spliterator}.
         *
         * @return a sequential {@code Stream} over the elements in this collection
         * @since 1.8
         */
        default Stream<E> stream() {
            return StreamSupport.stream(spliterator(), false);
        }
    /** * Returns a possibly parallel {@code Stream} with this collection as its * source. It is allowable for this method to return a sequential stream. * * <p>This method should be overridden when the {@link #spliterator()} * method cannot return a spliterator that is {@code IMMUTABLE}, * {@code CONCURRENT}, or <em>late-binding</em>. (See {@link #spliterator()} * for details.) * * @implSpec * The default implementation creates a parallel {@code Stream} from the * collection's {@code Spliterator}. * * @return a possibly parallel {@code Stream} over the elements in this * collection * @since 1.8 */ default Stream<E> parallelStream() { return StreamSupport.stream(spliterator(), true); } }

      Collection还有它的孩子们List、Set都可以通过parallelStream来创造一个Stream对象,然后才后面的那些lambda表达式。

  • 相关阅读:
    417 Pacific Atlantic Water Flow 太平洋大西洋水流
    416 Partition Equal Subset Sum 分割相同子集和
    415 Add Strings 字符串相加
    414 Third Maximum Number 第三大的数
    413 Arithmetic Slices 等差数列划分
    412 Fizz Buzz
    410 Split Array Largest Sum 分割数组的最大值
    409 Longest Palindrome 最长回文串
    day22 collection 模块 (顺便对比queue也学习了一下队列)
    day21 计算器作业
  • 原文地址:https://www.cnblogs.com/wuxun1997/p/9113255.html
Copyright © 2011-2022 走看看