使代碼更簡潔(一)---List相關

博客搬移到這裏:http://yemengying.com/
有個本身的博客還蠻好玩的,bazinga!java

記錄一下在工做開發中封裝的一些工具類,使代碼看起來更加的簡潔。這篇就記錄下和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 <T> void printList(List<T> list){
        if(null == list) list = new ArrayList<T>();
        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 <T> List<T> removeElementFromList(List<T> list, T arg){
        if(null == list || list.isEmpty()) return new ArrayList<T>();
        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<User> userList = new ArrayList<User>();
     *    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 <T> List<T> sortList(List<T> list, Comparator<? super T> comparator){
        if(null == list || list.isEmpty()) return new ArrayList<T>();
        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<User> userList = new ArrayList<User>();
     *    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 <T> boolean isAllMatch(List<T> list, Predicate<? super T> 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<User> userList = new ArrayList<User>();
     *    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 <T> boolean isAnyMatch(List<T> list, Predicate<? super T> 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<User> userList = new ArrayList<User>();
     *    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 <T> boolean isNoneMatch(List<T> list, Predicate<? super T> 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 <T> List<T> distinctList(List<T> list){
        if(null == list || list.isEmpty()) return new ArrayList<T>();
        return list.stream().distinct().collect(Collectors.toList());
    }
}

2利用泛型編寫一些通用的方法

方便的構造一個list

在開發時常常遇到要調用一個接口,接口的參數是list。例如在開發通知中心時發送消息的接口定義以下,其中messageForm是要發送的內容,userList是接受者的用戶id框架

public int pushMessage(MessageForm messageForm,List<Integer> userList);

這樣,在給一我的發送消息的時候也須要構造一個list
通常的作法,以下:工具

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

比較麻煩,因此同事封裝了一個工具方法:線程

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

這樣在調用時,比較簡潔:code

//給id 8808和8809發消息
pushService.pushMessage(messageForm,ListUtils.toList(8808,8809));

利用遞歸得到多個list的笛卡爾積

得到多個list的笛卡爾積,代碼參考stackoverfloworm

/**
     * 遞歸得到多個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 <T>  List<List<T>> cartesianProduct(List<List<T>> lists) {
        List<List<T>> resultLists = new ArrayList<List<T>>();
        if (lists.size() == 0) {
            resultLists.add(new ArrayList<T>());
            return resultLists;
        } else {
            List<T> firstList = lists.get(0);
            List<List<T>> remainingLists = cartesianProduct(lists.subList(1, lists.size()));
            for (T condition : firstList) {
                for (List<T> remainingList : remainingLists) {
                    ArrayList<T> resultList = new ArrayList<T>();
                    resultList.add(condition);
                    resultList.addAll(remainingList);
                    resultLists.add(resultList);
                }
            }
        }
        return resultLists;
    }

使用時將須要得到笛卡爾積的多個list放到一個list裏,調用上面的方法便可,調用示例以下:排序

List<Integer> list1 = Arrays.asList(1,2,3);
List<Integer> list2 = Arrays.asList(8808,8809,8810);
List<Integer> list3 = Arrays.asList(4);
List<List<Integer>> lists = Arrays.asList(list1,list2,list3);
List<List<Integer>> 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]]遞歸

相關文章
相關標籤/搜索