Java8——Stream_Lambda

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java8——Stream_Lambda相关的知识,希望对你有一定的参考价值。

前言:刚参加工作,对于同一个需求,我的代码虽然逻辑还算清晰,但相对用Java8新特性来写要繁琐很多,由此算是我真正学习Java8特性的一个开始(对于我这种小白来说这种接触新知识的能力还算不够)

Java8新特性可以参考:http://blog.csdn.net/yczz/article/details/50896975

注:这个项目是基于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——Stream_Lambda的主要内容,如果未能解决你的问题,请参考以下文章

java8 .stream().sorted().filter().map().collect()用法

Java8 Stream针对List先分组再求和最大值最小值平均值等

通过 Java 正则表达式提取 semver 版本字符串的片段

Java 8 新特性总结

Java Lambda

函数式编程