一、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() {
    }
}

image.png

二、定义转换后数据结构

@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;
    }
}

image.png

三、处理逻辑

@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.setSuce***esponse(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);
//                        }
//                    }
//                }
//            }
//        }
//    }
}