一、Optional
Java应用中最常见的bug就是空值异常。在Java 8之前,Google Guava引入了Optionals类来解决NullPointerException,从而避免源码被各种null检查污染,以便开发者写出更加整洁的代码。Java 8也将Optional加入了官方库。
Optional仅仅是一个容易:存放T类型的值或者null。它提供了一些有用的接口来避免显式的null检查。
API:
Modifier and Type | Method and Description |
---|---|
static |
empty() 返回一个空的 |
boolean |
equals(Object obj) 指示某个其他对象是否等于此可选项。 |
Optional |
filter(Predicate super T> predicate) 如果一个值存在,并且该值给定的谓词相匹配时,返回一个 |
Optional |
flatMap(Function super T,Optional> mapper) 如果一个值存在,应用提供的 |
T |
get() 如果 |
int |
hashCode() 返回当前值的哈希码值(如果有的话),如果没有值,则返回0(零)。 |
void |
ifPresent(Consumer super T> consumer) 如果存在值,则使用该值调用指定的消费者,否则不执行任何操作。 |
boolean |
isPresent() 返回 |
Optional |
map(Function super T,? extends U> mapper) 如果存在一个值,则应用提供的映射函数,如果结果不为空,则返回一个 |
static |
of(T value) 返回具有 |
static |
ofNullable(T value) 返回一个 |
T |
orElse(T other) 返回值如果存在,否则返回 |
T |
orElseGet(Supplier extends T> other) 返回值(如果存在),否则调用 |
|
orElseThrow(Supplier extends X> exceptionSupplier) 返回包含的值(如果存在),否则抛出由提供的供应商创建的异常。 |
String |
toString() 返回此可选的非空字符串表示,适用于调试。 |
二、Stream
参考:
http://blog.csdn.net/u010425776/article/details/52344425
http://blog.csdn.net/u010425776/article/details/52346644
API:
Modifier and Type | Method and Description |
---|---|
boolean |
allMatch(Predicate super T> predicate) 返回此流的所有元素是否与提供的谓词匹配。 |
boolean |
anyMatch(Predicate super T> predicate) 返回此流的任何元素是否与提供的谓词匹配。 |
static |
builder() 返回一个 |
|
collect(Collector super T,A,R> collector) 使用 Collector对此流的元素执行 mutable reduction |
|
collect(Supplier 对此流的元素执行 mutable reduction操作。 |
static |
concat(Stream extends T> a, Stream extends T> b) 创建一个懒惰连接的流,其元素是第一个流的所有元素,后跟第二个流的所有元素。 |
long |
count() 返回此流中的元素数。 |
Stream |
distinct() 返回由该流的不同元素(根据 |
static |
empty() 返回一个空的顺序 |
Stream |
filter(Predicate super T> predicate) 返回由与此给定谓词匹配的此流的元素组成的流。 |
Optional |
findAny() 返回描述流的一些元素的 |
Optional |
findFirst() 返回描述此流的第一个元素的 |
|
flatMap(Function super T,? extends Stream extends R>> mapper) 返回由通过将提供的映射函数应用于每个元素而产生的映射流的内容来替换该流的每个元素的结果的流。 |
DoubleStream |
flatMapToDouble(Function super T,? extends DoubleStream> mapper) 返回一个 |
IntStream |
flatMapToInt(Function super T,? extends IntStream> mapper) 返回一个 |
LongStream |
flatMapToLong(Function super T,? extends LongStream> mapper) 返回一个 |
void |
forEach(Consumer super T> action) 对此流的每个元素执行操作。 |
void |
forEachOrdered(Consumer super T> action) 如果流具有定义的遇到顺序,则以流的遇到顺序对该流的每个元素执行操作。 |
static |
generate(Supplier 返回无限顺序无序流,其中每个元素由提供的 |
static |
iterate(T seed, UnaryOperator 返回有序无限连续 |
Stream |
limit(long maxSize) 返回由此流的元素组成的流,截短长度不能超过 |
|
map(Function super T,? extends R> mapper) 返回由给定函数应用于此流的元素的结果组成的流。 |
DoubleStream |
mapToDouble(ToDoubleFunction super T> mapper) 返回一个 |
IntStream |
mapToInt(ToIntFunction super T> mapper) 返回一个 |
LongStream |
mapToLong(ToLongFunction super T> mapper) 返回一个 |
Optional |
max(Comparator super T> comparator) 根据提供的 |
Optional |
min(Comparator super T> comparator) 根据提供的 |
boolean |
noneMatch(Predicate super T> predicate) 返回此流的元素是否与提供的谓词匹配。 |
static |
of(T... values) 返回其元素是指定值的顺序排序流。 |
static |
of(T t) 返回包含单个元素的顺序 |
Stream |
peek(Consumer super T> action) 返回由该流的元素组成的流,另外在从生成的流中消耗元素时对每个元素执行提供的操作。 |
Optional |
reduce(BinaryOperator 使用 associative累积函数对此流的元素执行 reduction ,并返回描述减小值的 |
T |
reduce(T identity, BinaryOperator 使用提供的身份值和 associative累积功能对此流的元素执行 reduction ,并返回减小的值。 |
U |
reduce(U identity, BiFunction accumulator, BinaryOperator combiner) 执行 reduction在此流中的元素,使用所提供的身份,积累和组合功能。 |
Stream |
skip(long n) 在丢弃流的第一个 |
Stream |
sorted() 返回由此流的元素组成的流,根据自然顺序排序。 |
Stream |
sorted(Comparator super T> comparator) 返回由该流的元素组成的流,根据提供的 |
Object[] |
toArray() 返回一个包含此流的元素的数组。 |
A[] |
toArray(IntFunction generator) 使用提供的 |
三、Collectors
API:
Modifier and Type | Method and Description |
---|---|
static |
averagingDouble(ToDoubleFunction super T> mapper) 返回一个 |
static |
averagingInt(ToIntFunction super T> mapper) 返回一个 |
static |
averagingLong(ToLongFunction super T> mapper) 返回一个 |
static |
collectingAndThen(Collector 适应 |
static |
counting() 返回 |
static |
groupingBy(Function super T,? extends K> classifier) 返回 |
static |
groupingBy(Function super T,? extends K> classifier, Collector super T,A,D> downstream) 返回 |
static |
groupingBy(Function super T,? extends K> classifier, Supplier 返回 |
static |
groupingByConcurrent(Function super T,? extends K> classifier) 返回一个并发 |
static |
groupingByConcurrent(Function super T,? extends K> classifier, Collector super T,A,D> downstream) 返回一个并发 |
static |
groupingByConcurrent(Function super T,? extends K> classifier, Supplier 返回一个并发 |
static Collector |
joining() 返回一个 |
static Collector |
joining(CharSequence delimiter) 返回一个 |
static Collector |
joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix) 返回一个 |
static |
mapping(Function super T,? extends U> mapper, Collector super U,A,R> downstream) 适应一个 |
static |
maxBy(Comparator super T> comparator) 返回一个 |
static |
minBy(Comparator super T> comparator) 返回一个 |
static |
partitioningBy(Predicate super T> predicate) 返回一个 |
static |
partitioningBy(Predicate super T> predicate, Collector super T,A,D> downstream) 返回一个 |
static |
reducing(BinaryOperator 返回一个 |
static |
reducing(T identity, BinaryOperator 返回 |
static |
reducing(U identity, Function super T,? extends U> mapper, BinaryOperator op) 返回一个 |
static |
summarizingDouble(ToDoubleFunction super T> mapper) 返回一个 |
static |
summarizingInt(ToIntFunction super T> mapper) 返回一个 |
static |
summarizingLong(ToLongFunction super T> mapper) 返回一个 |
static |
summingDouble(ToDoubleFunction super T> mapper) 返回一个 |
static |
summingInt(ToIntFunction super T> mapper) 返回一个 |
static |
summingLong(ToLongFunction super T> mapper) 返回一个 |
static |
toCollection(Supplier 返回一个 |
static |
toConcurrentMap(Function super T,? extends K> keyMapper, Function super T,? extends U> valueMapper) 返回一个并发的 |
static |
toConcurrentMap(Function super T,? extends K> keyMapper, Function super T,? extends U> valueMapper, BinaryOperator mergeFunction) 返回一个并发的 |
static |
toConcurrentMap(Function super T,? extends K> keyMapper, Function super T,? extends U> valueMapper, BinaryOperator mergeFunction, Supplier 返回一个并发的 |
static |
toList() 返回一个 |
static |
toMap(Function super T,? extends K> keyMapper, Function super T,? extends U> valueMapper) 返回一个 |
static |
toMap(Function super T,? extends K> keyMapper, Function super T,? extends U> valueMapper, BinaryOperator mergeFunction) 返回一个 |
static |
toMap(Function super T,? extends K> keyMapper, Function super T,? extends U> valueMapper, BinaryOperator mergeFunction, Supplier 返回一个 |
static |
toSet() 返回一个 |
工作中应用:
注:这个项目微服务架构使用dubbo
一、转换前数据结构
@XmlRootElement @XmlAccessorType(XmlAccessType.FIELD) public class GeneTreeList extends ResponseBase { @XmlElements({@XmlElement( name = "tree", type = GeneTree.class )}) private ListtreeList = new ArrayList(); public GeneTreeList() { } public List getTreeList() { return this.treeList; } public void setTreeList(List 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 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 Listchilds = new ArrayList(); public LabelList(){} public List getChilds() { return childs; } public void setChilds(List 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 labels = new ArrayList(); public OutChild(){} public List getLabels() { return labels; } public void setLabels(List 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.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) { ListgeneTreeLabelList = 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 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 lableMap = geneTreeLabelList.stream().collect(Collectors.toMap(GeneTreeLabel::getLabelId, c -> c, (e1, e2) -> e1)); Map typeMap = geneTreeLabelList.stream().collect(Collectors.toMap(GeneTreeLabel::getTypeId, c -> c, (e1, e2) -> e1)); //按type分类 Map > groupbyType = geneTreeLabelList.stream().collect(groupingBy(GeneTreeLabel::getTypeId)); //遍历生成Childs //t是integer类型 //map是映射:将GeneTreeLabel转换成GeneTreeLabel.getTypeId()为int类型,然后去重 //然后将int类型映射成函数需要的类型 //注:第三行用到了得到的lableMap、typeMap、groupbyType List 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 treeList = geneTreeList.getTreeList(); // List childList = new ArrayList<>(); // getTreeList(treeList, childList); // labellist.setChilds(childList); } private static OutChild GeneTreeLabel2OutChild(GeneTreeLabel geneTreeLabel, Map > groupbyType, Map lableMap) { OutChild outChild = new OutChild(); outChild.setTypeId(geneTreeLabel.getTypeId()); outChild.setTypeName(geneTreeLabel.getTypeName()); //List 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 treeList, List childList) { // // Iterator it = treeList.iterator(); // while (it.hasNext()) { // GeneTree geneTree = it.next(); // List labels = geneTree.getLabels(); // setLabels(labels, childList); // } // } // // public static void setLabels(List labels, List childList) { // Iterator 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 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 it1 = childList.iterator(); // while (it1.hasNext()) { // OutChild outChild = it1.next(); // if (outChild.getTypeId() == label.getTypeId()) {//找到对应的child,然后查找child里面的label是否重复 // List outLabels = outChild.getLabels(); // Iterator 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); // } // } // } // } // } // } }