资讯专栏INFORMATION COLUMN

使代码更简洁(一)---List相关

lpjustdoit / 2540人阅读

摘要:就如同一个迭代器,单向,不可往复,数据只能遍历一次,遍历过一次后即用尽了,就好比流水从面前流过,一去不复返。而和迭代器又不同的是,可以并行化操作,迭代器只能命令式地串行化操作。

博客搬移到这里:http://yemengying.com/
有个自己的博客还蛮好玩的,bazinga!

记录一下在工作开发中封装的一些工具类,使代码看起来更加的简洁。这篇就记录下和list相关的吧。。。。。会持续记录。。。。

1利用stream代替for循环

在对list的操作中常常需要for循环来遍历整个list,代码看起来不够简洁。所以利用java8的新特性Stream来代替for循环,提高程序的可读性。
从网上coyp了一些stream的介绍:Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator。原始版本的 Iterator,用户只能显式地一个一个遍历元素并对其执行某些操作;高级版本的 Stream,用户只要给出需要对其包含的元素执行什么操作,比如 “过滤掉长度大于 10 的字符串”、“获取每个字符串的首字母”等,Stream 会隐式地在内部进行遍历,做出相应的数据转换。
Stream 就如同一个迭代器(Iterator),单向,不可往复,数据只能遍历一次,遍历过一次后即用尽了,就好比流水从面前流过,一去不复返。
而和迭代器又不同的是,Stream 可以并行化操作,迭代器只能命令式地、串行化操作。顾名思义,当使用串行方式去遍历时,每个 item 读完后再读下一个 item。而使用并行去遍历时,数据会被分成多个段,其中每一个都在不同的线程中处理,然后将结果一起输出。Stream 的并行操作依赖于 Java7 中引入的 Fork/Join 框架(JSR166y)来拆分任务和加速处理过程。
下面是一些利用stream写的工具类

打印list中的元素
/**
 * 
 * @author yemengying
 *
 */
public class ListUtils {
    /**
     * 打印list中的元素
     * @param list
     */
    public static  void printList(List list){
        if(null == list) list = new ArrayList();
        list.stream().forEach(n -> System.out.println(n.toString()));
    }
}
从list中删除指定的元素
/**
 * 
 * @author yemengying
 *  
 */
public class ListUtils {
    
    /**
     * 从list中删除指定的元素 其他类需重写equals方法
     * @param list
     * @param arg 要删除的元素
     * @return 返回删除了指定元素的list
     * eg:list:[1,2,3,1]---removeElementFromList(list,1)---return list:[2,3]
     */
    public static  List removeElementFromList(List list, T arg){
        if(null == list || list.isEmpty()) return new ArrayList();
        if(arg == null) return list;
        return list.stream().filter(n -> {
            return !n.equals(arg);
        }).collect(Collectors.toList());
    }
}
list排序
/**
 * 
 * @author yemengying
 *  
 */
public class ListUtils {
    /**
     * list排序
     * @param list
     * @param comparator
     * @return 返回按comparator排好序的list
     * eg:User:id name两个属性 
     *  List userList = new ArrayList();
     *    userList.add(new User(1,"abc"));
     *    userList.add(new User(3, "ccd"));
     *    userList.add(new User(2, "bde"));
     *    1.按user名字排序
     *    userList = ListUtils.sortList(userList, (p1, p2) -> p1.getName().compareTo(p2.getName()));
     *    2.按user Id排序
     *  userList = ListUtils.sortList(userList, (p1, p2) -> p1.getId()-p2.getId());
     */
    public static  List sortList(List list, Comparator comparator){
        if(null == list || list.isEmpty()) return new ArrayList();
        if(null == comparator) return list;
        return list.stream().sorted(comparator).collect(Collectors.toList());
        
    }
}    
判读list中的元素是不是全部满足 指定条件
/**
 * 
 * @author yemengying
 *  
 */
public class ListUtils {
    /**
     * 判读list中的元素是不是全部满足 predicate的条件 
     * @param list
     * @param predicate
     * @return 全部满足 true 有不满足的 false
     * eg:判断list中的user的id是不是均小于4
     * List userList = new ArrayList();
     *    userList.add(new User(1,"abc"));
     *    userList.add(new User(3, "ccd"));
     *    userList.add(new User(2, "bde"));
     *    System.out.println(ListUtils.isAllMatch(userList, u -> u.getId()<4));
     *  输出 true
     */
    public static  boolean isAllMatch(List list, Predicate predicate){
        if(null == list || list.isEmpty()) return false;
        if(null == predicate) return false;
        return list.stream().allMatch(predicate);
    }
}    
判断list中是不是有一个元素满足predicate的条件
/**
 * 
 * @author yemengying
 *  
 */
public class ListUtils {
    /**
     * 只要有一个元素满足predicate的条件 返回true
     * @param list
     * @param predicate
     * @return 
     * eg:判断list中的user的id是不是有一个大于4
     * List userList = new ArrayList();
     *    userList.add(new User(1,"abc"));
     *    userList.add(new User(3, "ccd"));
     *    userList.add(new User(2, "bde"));
     *    System.out.println(ListUtils.isAllMatch(userList, u -> u.getId()>4));  return false
     */ 
    public static  boolean isAnyMatch(List list, Predicate predicate){
        if(null == list || list.isEmpty()) return false;
        if(null == predicate) return false;
        return list.stream().anyMatch(predicate);
    }
}    
判断list中是不是没有一个元素满足predicate的条件
/**
 * 
 * @author yemengying
 *  
 */
public class ListUtils {
    /**
     * 没有一个元素满足predicate的条件 返回true
     * @param list
     * @param predicate
     * @return
     * eg:判断list中的user的id是不是有一个大于4
     * List userList = new ArrayList();
     *    userList.add(new User(1,"abc"));
     *    userList.add(new User(3, "ccd"));
     *    userList.add(new User(2, "bde"));
     *    System.out.println(ListUtils.isAllMatch(userList, u -> u.getId()>4));  return true
     */
    public static  boolean isNoneMatch(List list, Predicate predicate){
        if(null == list || list.isEmpty()) return false;
        if(null == predicate) return false;
        return list.stream().noneMatch(predicate);
    }
}    
list去重
/**
 * 
 * @author yemengying
 *  
 */
public class ListUtils {
    /**
     * list去重
     * @param list
     * @return
     * eg:
     * list[1,2,2]---distinctList(list)---list[1,2]
     */
    public static  List distinctList(List list){
        if(null == list || list.isEmpty()) return new ArrayList();
        return list.stream().distinct().collect(Collectors.toList());
    }
}    
2利用泛型编写一些通用的方法 方便的构造一个list

在开发时经常遇到要调用一个接口,接口的参数是list。例如在开发通知中心时发送消息的接口定义如下,其中messageForm是要发送的内容,userList是接受者的用户id

public int pushMessage(MessageForm messageForm,List userList);

这样,在给一个人发送消息的时候也需要构造一个list
一般的做法,如下:

List list = new ArrayList();
list.add(8808);
pushService.pushMessage(messageForm,list);

比较麻烦,所以同事封装了一个工具方法:

public class ListUtils {
     /**
     * 构造list
     * @param args
     * @return
     * @author zhoujianming
     */
    @SuppressWarnings("unchecked") 
    public static  List toList(T...args) {
        if (null == args) {
            return new ArrayList();
        }
        List list = new ArrayList();
        for (T t : args) {
            list.add(t);
        }
        return list;
    }
}

这样在调用时,比较简洁:

//给id 8808和8809发消息
pushService.pushMessage(messageForm,ListUtils.toList(8808,8809));
利用递归获得多个list的笛卡尔积

获得多个list的笛卡尔积,代码参考stackoverflow

    
    /**
     * 递归获得多个list的笛卡尔积
     * eg[1],[8808],[1,2,3]-->[[1,8808,1],[1,8808,2]]
     * 参考:http://stackoverflow.com/questions/714108/cartesian-product-of-arbitrary-sets-in-java
     * @param lists
     * @return
     */
    public static   List> cartesianProduct(List> lists) {
        List> resultLists = new ArrayList>();
        if (lists.size() == 0) {
            resultLists.add(new ArrayList());
            return resultLists;
        } else {
            List firstList = lists.get(0);
            List> remainingLists = cartesianProduct(lists.subList(1, lists.size()));
            for (T condition : firstList) {
                for (List remainingList : remainingLists) {
                    ArrayList resultList = new ArrayList();
                    resultList.add(condition);
                    resultList.addAll(remainingList);
                    resultLists.add(resultList);
                }
            }
        }
        return resultLists;
    }

使用时将需要获得笛卡尔积的多个list放到一个list里,调用上面的方法即可,调用示例如下:

List list1 = Arrays.asList(1,2,3);
List list2 = Arrays.asList(8808,8809,8810);
List list3 = Arrays.asList(4);
List> lists = Arrays.asList(list1,list2,list3);
List> resultLists = ListUtils.cartesianProduct(lists);

[1,2,3],[8808,8809,8810],[4]------>[[1, 8808, 4], [1, 8809, 4], [1, 8810, 4], [2, 8808, 4], [2, 8809, 4], [2, 8810, 4], [3, 8808, 4], [3, 8809, 4], [3, 8810, 4]]

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/64514.html

相关文章

  • 使代码简洁(二)----集合转换相关

    摘要:举个例子,在开发通知中心时需要给用户推送消息,安卓和是调用的不同的第三方库,所以要根据设备的类型调用不同的方法。接着要获得是的列表,是安卓的列表。 博客搬移到这里:http://yemengying.com/有个自己的博客还蛮好玩的,bazinga! 记录一下在工作开发中封装的一些工具类,使代码看起来更加的简洁。这篇就记录下和集合转换相关的吧。。。。。会持续记录。。。。 list转ma...

    meislzhua 评论0 收藏0
  • Ummm... Java8和lambda

    摘要:引入了与此前完全不同的函数式编程方法,通过表达式和来为下的函数式编程提供动力。命令式编程语言把对象变量和流转当作一等公民,而函数式编程在此基础上加入了策略变量这一新的一等公民。 Java8引入了与此前完全不同的函数式编程方法,通过Lambda表达式和StreamAPI来为Java下的函数式编程提供动力。本文是Java8新特性的第一篇,旨在阐释函数式编程的本义,更在展示Java是如何通...

    LMou 评论0 收藏0
  • 使用Java编程引导JPA

    摘要:从好的方面来说,只需使用普通的就可以在不使用文件的情况下引导实现。请注意,为简洁起见,我们省略了类案例结论在本文中,我们展示了如何使用的接口和的类的自定义实现以编程方式引导实体管理器,而不必依赖传统的文件。 案例概述 大多数JPA驱动的应用程序大量使用persistence.xml文件来获取JPA实现,例如Hibernate或OpenJPA。 我们的方法提供了一种集中式机制,用于配置一...

    ymyang 评论0 收藏0
  • Java™ 教程(Lambda表达式)

    Lambda表达式 匿名类的一个问题是,如果匿名类的实现非常简单,例如只包含一个方法的接口,那么匿名类的语法可能看起来不实用且不清楚,在这些情况下,你通常会尝试将功能作为参数传递给另一个方法,例如当有人单击按钮时应采取的操作,Lambda表达式使你可以执行此操作,将功能视为方法参数,或将代码视为数据。 上一节匿名类向你展示了如何在不给它命名的情况下实现基类,虽然这通常比命名类更简洁,但对于只有一个...

    lansheng228 评论0 收藏0
  • Java8实用技能

    大概一年多之前,我对java8的理解还仅限一些只言片语的文章之上,后来出于对函数式编程的兴趣,买了本参考书看了一遍,然后放在了书架上,后来,当我接手大客户应用的开发工作之后,java8的一些工具,对我的效率有了不小的提升,因此想记录一下java8的一些常用场景,我希望这会成为一个小字典,能让我免于频繁翻书,但是总能找到自己想找的知识。 用于举例的model: @Data public class ...

    microcosm1994 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<