1. 程式人生 > >Java8新特性-官方庫新特性

Java8新特性-官方庫新特性

identity nis brush else reat 均值 emp lba long

一、Optional

Java應用中最常見的bug就是空值異常。在Java 8之前,Google Guava引入了Optionals類來解決NullPointerException,從而避免源碼被各種null檢查汙染,以便開發者寫出更加整潔的代碼。Java 8也將Optional加入了官方庫。

Optional僅僅是一個容易:存放T類型的值或者null。它提供了一些有用的接口來避免顯式的null檢查。

API:

Modifier and TypeMethod and Description
static <T> Optional<T>empty()

返回一個空的 Optional

實例。

booleanequals(Object obj)

指示某個其他對象是否等於此可選項。

Optional<T>filter(Predicate<? super T> predicate)

如果一個值存在,並且該值給定的謂詞相匹配時,返回一個 Optional描述的值,否則返回一個空的 Optional

<U> Optional<U>flatMap(Function<? super T,Optional<U>> mapper)

如果一個值存在,應用提供的 Optional映射函數給它,返回該結果,否則返回一個空的 Optional

Tget()

如果 Optional中有一個值,返回值,否則拋出 NoSuchElementException

inthashCode()

返回當前值的哈希碼值(如果有的話),如果沒有值,則返回0(零)。

voidifPresent(Consumer<? super T> consumer)

如果存在值,則使用該值調用指定的消費者,否則不執行任何操作。

booleanisPresent()

返回 true如果存在值,否則為 false

<U> Optional<U>map(Function<? super T,? extends U> mapper)

如果存在一個值,則應用提供的映射函數,如果結果不為空,則返回一個 Optional結果的 Optional

static <T> Optional<T>of(T value)

返回具有 Optional的當前非空值的Optional。

static <T> Optional<T>ofNullable(T value)

返回一個 Optional指定值的Optional,如果非空,則返回一個空的 Optional

TorElse(T other)

返回值如果存在,否則返回 other

TorElseGet(Supplier<? extends T> other)

返回值(如果存在),否則調用 other並返回該調用的結果。

<X extends Throwable>
T
orElseThrow(Supplier<? extends X> exceptionSupplier)

返回包含的值(如果存在),否則拋出由提供的供應商創建的異常。

StringtoString()

返回此可選的非空字符串表示,適用於調試。


二、Stream

參考:

http://blog.csdn.net/u010425776/article/details/52344425

http://blog.csdn.net/u010425776/article/details/52346644

API:

Modifier and TypeMethod and Description
booleanallMatch(Predicate<? super T> predicate)

返回此流的所有元素是否與提供的謂詞匹配。

booleananyMatch(Predicate<? super T> predicate)

返回此流的任何元素是否與提供的謂詞匹配。

static <T> Stream.Builder<T>builder()

返回一個 Stream的構建器。

<R,A> Rcollect(Collector<? super T,A,R> collector)

使用 Collector對此流的元素執行 mutable reduction Collector

<R> Rcollect(Supplier<R> supplier, BiConsumer<R,? super T> accumulator, BiConsumer<R,R> combiner)

對此流的元素執行 mutable reduction操作。

static <T> Stream<T>concat(Stream<? extends T> a, Stream<? extends T> b)

創建一個懶惰連接的流,其元素是第一個流的所有元素,後跟第二個流的所有元素。

longcount()

返回此流中的元素數。

Stream<T>distinct()

返回由該流的不同元素(根據 Object.equals(Object) )組成的流。

static <T> Stream<T>empty()

返回一個空的順序 Stream

Stream<T>filter(Predicate<? super T> predicate)

返回由與此給定謂詞匹配的此流的元素組成的流。

Optional<T>findAny()

返回描述流的一些元素的Optional如果流為空,則返回一個空的Optional

Optional<T>findFirst()

返回描述此流的第一個元素的Optional如果流為空,則返回一個空的Optional

<R> Stream<R>flatMap(Function<? super T,? extends Stream<? extends R>> mapper)

返回由通過將提供的映射函數應用於每個元素而產生的映射流的內容來替換該流的每個元素的結果的流。

DoubleStreamflatMapToDouble(Function<? super T,? extends DoubleStream> mapper)

返回一個 DoubleStream ,其中包含將該流的每個元素替換為通過將提供的映射函數應用於每個元素而產生的映射流的內容的結果。

IntStreamflatMapToInt(Function<? super T,? extends IntStream> mapper)

返回一個 IntStream ,其中包含將該流的每個元素替換為通過將提供的映射函數應用於每個元素而產生的映射流的內容的結果。

LongStreamflatMapToLong(Function<? super T,? extends LongStream> mapper)

返回一個 LongStream ,其中包含將該流的每個元素替換為通過將提供的映射函數應用於每個元素而產生的映射流的內容的結果。

voidforEach(Consumer<? super T> action)

對此流的每個元素執行操作。

voidforEachOrdered(Consumer<? super T> action)

如果流具有定義的遇到順序,則以流的遇到順序對該流的每個元素執行操作。

static <T> Stream<T>generate(Supplier<T> s)

返回無限順序無序流,其中每個元素由提供的 Supplier

static <T> Stream<T>iterate(T seed, UnaryOperator<T> f)

返回有序無限連續 Stream由函數的叠代應用產生 f至初始元素 seed ,產生 Stream包括 seedf(seed)f(f(seed)) ,等

Stream<T>limit(long maxSize)

返回由此流的元素組成的流,截短長度不能超過 maxSize

<R> Stream<R>map(Function<? super T,? extends R> mapper)

返回由給定函數應用於此流的元素的結果組成的流。

DoubleStreammapToDouble(ToDoubleFunction<? super T> mapper)

返回一個 DoubleStream ,其中包含將給定函數應用於此流的元素的結果。

IntStreammapToInt(ToIntFunction<? super T> mapper)

返回一個 IntStream ,其中包含將給定函數應用於此流的元素的結果。

LongStreammapToLong(ToLongFunction<? super T> mapper)

返回一個 LongStream ,其中包含將給定函數應用於此流的元素的結果。

Optional<T>max(Comparator<? super T> comparator)

根據提供的 Comparator返回此流的最大元素。

Optional<T>min(Comparator<? super T> comparator)

根據提供的 Comparator返回此流的最小元素。

booleannoneMatch(Predicate<? super T> predicate)

返回此流的元素是否與提供的謂詞匹配。

static <T> Stream<T>of(T... values)

返回其元素是指定值的順序排序流。

static <T> Stream<T>of(T t)

返回包含單個元素的順序 Stream

Stream<T>peek(Consumer<? super T> action)

返回由該流的元素組成的流,另外在從生成的流中消耗元素時對每個元素執行提供的操作。

Optional<T>reduce(BinaryOperator<T> accumulator)

使用 associative累積函數對此流的元素執行 reduction ,並返回描述減小值的 Optional (如果有)。

Treduce(T identity, BinaryOperator<T> accumulator)

使用提供的身份值和 associative累積功能對此流的元素執行 reduction ,並返回減小的值。

<U> Ureduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)

執行 reduction在此流中的元素,使用所提供的身份,積累和組合功能。

Stream<T>skip(long n)

在丟棄流的第一個 n元素後,返回由該流的 n元素組成的流。

Stream<T>sorted()

返回由此流的元素組成的流,根據自然順序排序。

Stream<T>sorted(Comparator<? super T> comparator)

返回由該流的元素組成的流,根據提供的 Comparator進行排序。

Object[]toArray()

返回一個包含此流的元素的數組。

<A> A[]toArray(IntFunction<A[]> generator)

使用提供的 generator函數返回一個包含此流的元素的數組,以分配返回的數組,以及分區執行或調整大小可能需要的任何其他數組。


三、Collectors

API:

Modifier and TypeMethod and Description
static <T> Collector<T,?,Double>averagingDouble(ToDoubleFunction<? super T> mapper)

返回一個 Collector ,它產生應用於輸入元素的雙值函數的算術平均值。

static <T> Collector<T,?,Double>averagingInt(ToIntFunction<? super T> mapper)

返回一個 Collector ,它產生應用於輸入元素的整數值函數的算術平均值。

static <T> Collector<T,?,Double>averagingLong(ToLongFunction<? super T> mapper)

返回一個 Collector ,它產生應用於輸入元素的長值函數的算術平均值。

static <T,A,R,RR> Collector<T,A,RR>collectingAndThen(Collector<T,A,R> downstream, Function<R,RR> finisher)

適應 Collector進行額外的整理轉換。

static <T> Collector<T,?,Long>counting()

返回 Collector類型的接受元件 T計數輸入元件的數量。

static <T,K> Collector<T,?,Map<K,List<T>>>groupingBy(Function<? super T,? extends K> classifier)

返回 Collector “由基團”上的類型的輸入元件操作實現 T ,根據分類功能分組元素,並且在返回的結果 Map

static <T,K,A,D> Collector<T,?,Map<K,D>>groupingBy(Function<? super T,? extends K> classifier, Collector<? super T,A,D> downstream)

返回 Collector “由基團”上的類型的輸入元件操作實現級聯 T ,根據分類功能分組元素,然後使用下遊的指定執行與給定鍵相關聯的值的歸約運算 Collector

static <T,K,D,A,M extends Map<K,D>>
Collector<T,?,M>
groupingBy(Function<? super T,? extends K> classifier, Supplier<M> mapFactory, Collector<? super T,A,D> downstream)

返回 Collector “由基團”上的類型的輸入元件操作實現級聯 T ,根據分類功能分組元素,然後使用下遊的指定執行與給定鍵相關聯的值的歸約運算 Collector

static <T,K> Collector<T,?,ConcurrentMap<K,List<T>>>groupingByConcurrent(Function<? super T,? extends K> classifier)

返回一個並發 Collector “由基團”上的類型的輸入元件操作實現 T ,根據分類功能分組元素。

static <T,K,A,D> Collector<T,?,ConcurrentMap<K,D>>groupingByConcurrent(Function<? super T,? extends K> classifier, Collector<? super T,A,D> downstream)

返回一個並發 Collector “由基團”上的類型的輸入元件操作實現級聯 T ,根據分類功能分組元素,然後使用下遊的指定執行與給定鍵相關聯的值的歸約運算 Collector

static <T,K,A,D,M extends ConcurrentMap<K,D>>
Collector<T,?,M>
groupingByConcurrent(Function<? super T,? extends K> classifier, Supplier<M> mapFactory, Collector<? super T,A,D> downstream)

返回一個並發 Collector “由基團”上的類型的輸入元件操作實現級聯 T ,根據分類功能分組元素,然後使用下遊的指定執行與給定鍵相關聯的值的歸約運算 Collector

static Collector<CharSequence,?,String>joining()

返回一個 Collector ,按照遇到的順序將輸入元素連接到一個 String中。

static Collector<CharSequence,?,String>joining(CharSequence delimiter)

返回一個 Collector ,按照遇到的順序連接由指定的分隔符分隔的輸入元素。

static Collector<CharSequence,?,String>joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix)

返回一個 Collector ,它將按照指定的 Collector分隔的輸入元素與指定的前綴和後綴進行連接。

static <T,U,A,R> Collector<T,?,R>mapping(Function<? super T,? extends U> mapper, Collector<? super U,A,R> downstream)

適應一個 Collector類型的接受元件 U至類型的一個接受元件 T通過積累前應用映射函數到每個輸入元素。

static <T> Collector<T,?,Optional<T>>maxBy(Comparator<? super T> comparator)

返回一個 Collector ,它根據給出的 Comparator產生最大元素,描述為 Optional<T>

static <T> Collector<T,?,Optional<T>>minBy(Comparator<? super T> comparator)

返回一個 Collector ,根據給出的 Comparator產生最小元素,描述為 Optional<T>

static <T> Collector<T,?,Map<Boolean,List<T>>>partitioningBy(Predicate<? super T> predicate)

返回一個 Collector ,根據Predicate對輸入元素進行 Predicate ,並將它們組織成 Map<Boolean, List<T>>

static <T,D,A> Collector<T,?,Map<Boolean,D>>partitioningBy(Predicate<? super T> predicate, Collector<? super T,A,D> downstream)

返回一個 Collector ,它根據Predicate對輸入元素進行 Predicate ,根據另一個 Collector減少每個分區的值,並將其組織成 Map<Boolean, D> ,其值是下遊縮減的結果。

static <T> Collector<T,?,Optional<T>>reducing(BinaryOperator<T> op)

返回一個 Collector ,它在指定的 Collector下執行其輸入元素的 BinaryOperator

static <T> Collector<T,?,T>reducing(T identity, BinaryOperator<T> op)

返回 Collector執行下一個指定的減少其輸入元件的 BinaryOperator使用所提供的身份。

static <T,U> Collector<T,?,U>reducing(U identity, Function<? super T,? extends U> mapper, BinaryOperator<U> op)

返回一個 Collector ,它在指定的映射函數和 BinaryOperator下執行其輸入元素的 BinaryOperator

static <T> Collector<T,?,DoubleSummaryStatistics>summarizingDouble(ToDoubleFunction<? super T> mapper)

返回一個 Collectordouble生產映射函數應用於每個輸入元素,並返回結果值的匯總統計信息。

static <T> Collector<T,?,IntSummaryStatistics>summarizingInt(ToIntFunction<? super T> mapper)

返回一個 Collectorint生產映射函數應用於每個輸入元素,並返回結果值的匯總統計信息。

static <T> Collector<T,?,LongSummaryStatistics>summarizingLong(ToLongFunction<? super T> mapper)

返回一個 Collectorlong生產映射函數應用於每個輸入元素,並返回結果值的匯總統計信息。

static <T> Collector<T,?,Double>summingDouble(ToDoubleFunction<? super T> mapper)

返回一個 Collector ,它產生應用於輸入元素的雙值函數的和。

static <T> Collector<T,?,Integer>summingInt(ToIntFunction<? super T> mapper)

返回一個 Collector ,它產生應用於輸入元素的整數值函數的和。

static <T> Collector<T,?,Long>summingLong(ToLongFunction<? super T> mapper)

返回一個 Collector ,它產生應用於輸入元素的長值函數的和。

static <T,C extends Collection<T>>
Collector<T,?,C>
toCollection(Supplier<C> collectionFactory)

返回一個 Collector ,按照遇到的順序將輸入元素累加到一個新的 Collection中。

static <T,K,U> Collector<T,?,ConcurrentMap<K,U>>toConcurrentMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper)

返回一個並發的 Collector ,它將元素累加到 ConcurrentMap ,其鍵和值是將所提供的映射函數應用於輸入元素的結果。

static <T,K,U> Collector<T,?,ConcurrentMap<K,U>>toConcurrentMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction)

返回一個並發的 Collector ,它將元素累加到一個 ConcurrentMap ,其鍵和值是將提供的映射函數應用於輸入元素的結果。

static <T,K,U,M extends ConcurrentMap<K,U>>
Collector<T,?,M>
toConcurrentMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier)

返回一個並發的 Collector ,它將元素累加到一個 ConcurrentMap ,其鍵和值是將所提供的映射函數應用於輸入元素的結果。

static <T> Collector<T,?,List<T>>toList()

返回一個 Collector ,它將輸入元素 List到一個新的 List

static <T,K,U> Collector<T,?,Map<K,U>>toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper)

返回一個 Collector ,它將元素累加到一個 Map ,其鍵和值是將所提供的映射函數應用於輸入元素的結果。

static <T,K,U> Collector<T,?,Map<K,U>>toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction)

返回一個 Collector ,它將元素累加到 Map ,其鍵和值是將提供的映射函數應用於輸入元素的結果。

static <T,K,U,M extends Map<K,U>>
Collector<T,?,M>
toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier)

返回一個 Collector ,它將元素累加到一個 Map ,其鍵和值是將所提供的映射函數應用於輸入元素的結果。

static <T> Collector<T,?,Set<T>>toSet()

返回一個 Collector ,將輸入元素 Set到一個新的 Set


工作中應用:

註:這個項目微服務架構使用dubbo

一、轉換前數據結構

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class GeneTreeList extends ResponseBase {
    @XmlElements({@XmlElement(
    name = "tree",
    type = GeneTree.class
)})
    private List<GeneTree> treeList = new ArrayList();

    public GeneTreeList() {
    }

    public List<GeneTree> getTreeList() {
        return this.treeList;
    }

    public void setTreeList(List<GeneTree> treeList) {
        this.treeList = treeList;
    }
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class GeneTree extends ResponseBase {
    @XmlAttribute
    private int portalId;
    @XmlAttribute
    private int parentTreeId;
    @XmlAttribute
    private int treeId;
    @XmlAttribute
    private int treeType;
    @XmlAttribute
    private int layer;
    @XmlAttribute
    private int order;
    private String treeName;
    private boolean isLeaf;
    private String template;
    private int retrieveId;
    private int filmCount;
    private String icon = "";
    private String backgroundImg = "";
    private String cpid = "";
    private String copyright = "";
    private int movieLimitCount;
    private int movieAuditCount;
    private String moviePosterLimit = "";
    private Date updatetime;
    private Date createtime;
    @XmlElements({@XmlElement(
    name = "label",
    type = GeneTreeLabel.class
)})
    private List<GeneTreeLabel> labels = new ArrayList();

    public GeneTree() {
    }
//get/set方法
。。。。。。
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class GeneTreeLabel implements Serializable {
    @XmlAttribute
    private int typeId;
    @XmlAttribute
    private String typeName = "";
    @XmlAttribute
    private int labelId;
    @XmlAttribute
    private String labelName = "";

    public GeneTreeLabel() {
    }
}

技術分享圖片

二、定義轉換後數據結構

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class LabelList extends ResponseBase {
    @XmlElements({@XmlElement(
            name = "Child",
            type = OutChild.class
    )})
    private List<OutChild> childs = new ArrayList();

    public LabelList(){}

    public List<OutChild> getChilds() {
        return childs;
    }

    public void setChilds(List<OutChild> childs) {
        this.childs = childs;
    }
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class OutChild extends ResponseBase {
    @XmlAttribute
    private String typeName;
    @XmlAttribute
    private  int typeId;

    @XmlElements({@XmlElement(
            name = "label",
            type = OutLabel.class
    )})
    private List<OutLabel> labels = new ArrayList();
    public OutChild(){}

    public List<OutLabel> getLabels() {
        return labels;
    }

    public void setLabels(List<OutLabel> labels) {
        this.labels = labels;
    }

    public void setTypeName(String typeName) {
        this.typeName = typeName;
    }

    public void setTypeId(int typeId) {
        this.typeId = typeId;
    }

    public String getTypeName() {

        return typeName;
    }

    public int getTypeId() {
        return typeId;
    }
}

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public class OutLabel extends ResponseBase {
    @XmlAttribute
    private int labelId;
    @XmlAttribute
    private String labelName;

    public OutLabel(){}

    public int getLabelId() {
        return labelId;
    }

    public void setLabelId(int labelId) {
        this.labelId = labelId;
    }

    public String getLabelName() {
        return labelName;
    }

    public void setLabelName(String labelName) {
        this.labelName = labelName;
    }
}

技術分享圖片

三、處理邏輯

@Override
public LabelList labellist(Integer epgid) {
    LabelList labelList = new LabelList();

    if (epgid == null) {
        labelList.setParamInvalidResponse("epgId", String.valueOf(epgid));
        return labelList;
    }
    int treeid = 0;
    boolean opl = true;
    //geneTreeList-->labelList
    GeneTreeList geneTreeList = treeService.getTreeList(epgid, treeid, opl);

    if (null == geneTreeList) {
        labelList.setNoDataResponse();
        return labelList;
    }

    if (geneTreeList.getTreeList().size() > 0) {
        ChangeIbsTreeList.change(labelList, geneTreeList);
        labelList.setSucessResponse(ResponseStatus.Source.None);
    } else {
        labelList.setNoDataResponse();
    }
    return labelList;
}

下面代碼中註釋的是我寫的邏輯,很原始的方法。

public class ChangeIbsTreeList {
//    private static boolean[] flag1 = new boolean[100];//以typeid為數組下標

    public static void change(LabelList labellist, GeneTreeList geneTreeList) {

        List<GeneTreeLabel> geneTreeLabelList = new LinkedList<>();


        //獲取所有的label
        for (GeneTree geneTree : geneTreeList.getTreeList()) {
            geneTreeLabelList.addAll(geneTree.getLabels());
        }
        if (geneTreeLabelList.size() == 0) {
            return;
        }
        //根據lableid和typeid生成不同的map
		//geneTreeLabelList.stream():可以用來獲取流,參考:http://blog.csdn.net/u010425776/article/details/52344425  http://blog.csdn.net/u010425776/article/details/52346644
		//根據List創建Map:Map<Integer, Integer> map = list.stream().collect(Collectors.toMap(p -> p, q->q*3));
		//Collectors.toMap(GeneTreeLabel::getLabelId, c -> c, (e1, e2) -> e1):
			//	GeneTreeLabel::getLabelId:是接收一個任務並產生一個只包含該任務標題的鍵的Function
			//	 c -> c:一個用來返回任務本身的lambda表達式:http://www.importnew.com/16436.html   http://blog.csdn.net/u010425776/article/details/52334455
			//	(e1, e2) -> e1:處理重復問題
        Map<Integer, GeneTreeLabel> lableMap = geneTreeLabelList.stream().collect(Collectors.toMap(GeneTreeLabel::getLabelId, c -> c, (e1, e2) -> e1));
        Map<Integer, GeneTreeLabel> typeMap = geneTreeLabelList.stream().collect(Collectors.toMap(GeneTreeLabel::getTypeId, c -> c, (e1, e2) -> e1));
        //按type分類
        Map<Integer, List<GeneTreeLabel>> groupbyType =
                geneTreeLabelList.stream().collect(groupingBy(GeneTreeLabel::getTypeId));

        //遍歷生成Childs
		//t是integer類型
		//map是映射:將GeneTreeLabel轉換成GeneTreeLabel.getTypeId()為int類型,然後去重
		//然後將int類型映射成函數需要的類型
		//註:第三行用到了得到的lableMap、typeMap、groupbyType
        List<OutChild> OutChilds =
                (geneTreeLabelList.stream().map(GeneTreeLabel -> GeneTreeLabel.getTypeId()).distinct().collect(Collectors.toList()))
                        .stream().map(t -> GeneTreeLabel2OutChild(typeMap.get(t), groupbyType, lableMap)).collect(Collectors.toList());


        //遍歷Childs,set Labels
        for (OutChild child : OutChilds) {
            child.setLabels((groupbyType.get(child.getTypeId()).stream().map(GeneTreeLabel::getLabelId).distinct().collect(Collectors.toList())).stream().map(t -> GeneTreeLabel2OutLabel(lableMap.get(t))).collect(Collectors.toList()));
        }
        labellist.setChilds(OutChilds);

//        for (int i = 0; i < flag1.length; i++) {
//            flag1[i] = false;
//        }
//        List<GeneTree> treeList = geneTreeList.getTreeList();
//        List<OutChild> childList = new ArrayList<>();
//        getTreeList(treeList, childList);
//        labellist.setChilds(childList);
    }

    private static OutChild GeneTreeLabel2OutChild(GeneTreeLabel geneTreeLabel, Map<Integer, List<GeneTreeLabel>> groupbyType, Map<Integer, GeneTreeLabel> lableMap) {
        OutChild outChild = new OutChild();
        outChild.setTypeId(geneTreeLabel.getTypeId());
        outChild.setTypeName(geneTreeLabel.getTypeName());

        //List<OutLabel> labels = (groupbyType.get(geneTreeLabel.getTypeId()).stream().map(GeneTreeLabel -> GeneTreeLabel.getLabelId()).distinct().collect(Collectors.toList())).stream().map(t -> GeneTreeLabel2OutLabel(lableMap.get(t))).collect(Collectors.toList());

        //OutChild.setLabels(null);
        return outChild;
    }

    private static OutLabel GeneTreeLabel2OutLabel(GeneTreeLabel geneTreeLabel) {
        OutLabel outLabel = new OutLabel();
        outLabel.setLabelId(geneTreeLabel.getLabelId());
        outLabel.setLabelName(geneTreeLabel.getLabelName());
        return outLabel;
    }

//    public static void getTreeList(List<GeneTree> treeList, List<OutChild> childList) {
//
//        Iterator<GeneTree> it = treeList.iterator();
//        while (it.hasNext()) {
//            GeneTree geneTree = it.next();
//            List<GeneTreeLabel> labels = geneTree.getLabels();
//            setLabels(labels, childList);
//        }
//    }
//
//    public static void setLabels(List<GeneTreeLabel> labels, List<OutChild> childList) {
//        Iterator<GeneTreeLabel> it = labels.iterator();
//        while (it.hasNext()) {
//            GeneTreeLabel label = it.next();
//
//            if (false == flag1[label.getTypeId()]) {//如果標誌為false,說明child不存在
//                OutChild outChild = new OutChild();
//                outChild.setTypeId(label.getTypeId());
//                outChild.setTypeName(label.getTypeName());
//
//                List<OutLabel> outLabellist = new ArrayList<>();
//                OutLabel outLabel = new OutLabel();
//                outLabel.setLabelId(label.getLabelId());
//                outLabel.setLabelName(label.getLabelName());
//                outLabellist.add(outLabel);
//
//                outChild.setLabels(outLabellist);
//
//                childList.add(outChild);
//
//                flag1[label.getTypeId()] = true;
//            } else {                                 //否則已經建立這個類型的child,然後遍歷child集合,找到對應的child
//                Iterator<OutChild> it1 = childList.iterator();
//                while (it1.hasNext()) {
//                    OutChild outChild = it1.next();
//                    if (outChild.getTypeId() == label.getTypeId()) {//找到對應的child,然後查找child裏面的label是否重復
//                        List<OutLabel> outLabels = outChild.getLabels();
//                        Iterator<OutLabel> it2 = outLabels.iterator();
//                        int i = 0;
//                        while (it2.hasNext()) {//遍歷得到label
//                            OutLabel outLabel = it2.next();
//                            if (outLabel.getLabelId() == label.getLabelId()) {
//                                break;
//                            }
//                            i = i + 1;
//                        }
//                        if (i >= outLabels.size()) {
//                            OutLabel outLabel = new OutLabel();
//                            outLabel.setLabelId(label.getLabelId());
//                            outLabel.setLabelName(label.getLabelName());
//                            outLabels.add(outLabel);
//
//                            outChild.setLabels(outLabels);
//                        }
//                    }
//                }
//            }
//        }
//    }
}


Java8新特性-官方庫新特性