一、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 <T> Optional<T> | empty() 返回一个空的 |
boolean | equals(Object obj) 指示某个其他对象是否等于此可选项。 |
Optional<T> | filter(Predicate<? super T> predicate) 如果一个值存在,并且该值给定的谓词相匹配时,返回一个 |
<U> Optional<U> | flatMap(Function<? super T,Optional<U>> mapper) 如果一个值存在,应用提供的 |
T | get() 如果 |
int | hashCode() 返回当前值的哈希码值(如果有的话),如果没有值,则返回0(零)。 |
void | ifPresent(Consumer<? super T> consumer) 如果存在值,则使用该值调用指定的消费者,否则不执行任何操作。 |
boolean | isPresent() 返回 |
<U> Optional<U> | map(Function<? super T,? extends U> mapper) 如果存在一个值,则应用提供的映射函数,如果结果不为空,则返回一个 |
static <T> Optional<T> | of(T value) 返回具有 |
static <T> Optional<T> | ofNullable(T value) 返回一个 |
T | orElse(T other) 返回值如果存在,否则返回 |
T | orElseGet(Supplier<? extends T> other) 返回值(如果存在),否则调用 |
<X extends Throwable> | 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 <T> Stream.Builder<T> | builder() 返回一个 |
<R,A> R | collect(Collector<? super T,A,R> collector) 使用 Collector对此流的元素执行 mutable reduction |
<R> R | collect(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) 创建一个懒惰连接的流,其元素是第一个流的所有元素,后跟第二个流的所有元素。 |
long | count() 返回此流中的元素数。 |
Stream<T> | distinct() 返回由该流的不同元素(根据 |
static <T> Stream<T> | empty() 返回一个空的顺序 |
Stream<T> | filter(Predicate<? super T> predicate) 返回由与此给定谓词匹配的此流的元素组成的流。 |
Optional<T> | findAny() 返回描述流的一些元素的 |
Optional<T> | findFirst() 返回描述此流的第一个元素的 |
<R> Stream<R> | 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 <T> Stream<T> | generate(Supplier<T> s) 返回无限顺序无序流,其中每个元素由提供的 |
static <T> Stream<T> | iterate(T seed, UnaryOperator<T> f) 返回有序无限连续 |
Stream<T> | limit(long maxSize) 返回由此流的元素组成的流,截短长度不能超过 |
<R> Stream<R> | 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<T> | max(Comparator<? super T> comparator) 根据提供的 |
Optional<T> | min(Comparator<? super T> comparator) 根据提供的 |
boolean | noneMatch(Predicate<? super T> predicate) 返回此流的元素是否与提供的谓词匹配。 |
static <T> Stream<T> | of(T... values) 返回其元素是指定值的顺序排序流。 |
static <T> Stream<T> | of(T t) 返回包含单个元素的顺序 |
Stream<T> | peek(Consumer<? super T> action) 返回由该流的元素组成的流,另外在从生成的流中消耗元素时对每个元素执行提供的操作。 |
Optional<T> | reduce(BinaryOperator<T> accumulator) 使用 associative累积函数对此流的元素执行 reduction ,并返回描述减小值的 |
T | reduce(T identity, BinaryOperator<T> accumulator) 使用提供的身份值和 associative累积功能对此流的元素执行 reduction ,并返回减小的值。 |
<U> U | reduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner) 执行 reduction在此流中的元素,使用所提供的身份,积累和组合功能。 |
Stream<T> | skip(long n) 在丢弃流的第一个 |
Stream<T> | sorted() 返回由此流的元素组成的流,根据自然顺序排序。 |
Stream<T> | sorted(Comparator<? super T> comparator) 返回由该流的元素组成的流,根据提供的 |
Object[] | toArray() 返回一个包含此流的元素的数组。 |
<A> A[] | toArray(IntFunction<A[]> generator) 使用提供的 |
三、Collectors
API:
Modifier and Type | Method and Description |
---|---|
static <T> Collector<T,?,Double> | averagingDouble(ToDoubleFunction<? super T> mapper) 返回一个 |
static <T> Collector<T,?,Double> | averagingInt(ToIntFunction<? super T> mapper) 返回一个 |
static <T> Collector<T,?,Double> | averagingLong(ToLongFunction<? super T> mapper) 返回一个 |
static <T,A,R,RR> Collector<T,A,RR> | collectingAndThen(Collector<T,A,R> downstream, Function<R,RR> finisher) 适应 |
static <T> Collector<T,?,Long> | counting() 返回 |
static <T,K> Collector<T,?,Map<K,List<T>>> | groupingBy(Function<? super T,? extends K> classifier) 返回 |
static <T,K,A,D> Collector<T,?,Map<K,D>> | groupingBy(Function<? super T,? extends K> classifier, Collector<? super T,A,D> downstream) 返回 |
static <T,K,D,A,M extends Map<K,D>> | groupingBy(Function<? super T,? extends K> classifier, Supplier<M> mapFactory, Collector<? super T,A,D> downstream) 返回 |
static <T,K> Collector<T,?,ConcurrentMap<K,List<T>>> | groupingByConcurrent(Function<? super T,? extends K> classifier) 返回一个并发 |
static <T,K,A,D> Collector<T,?,ConcurrentMap<K,D>> | groupingByConcurrent(Function<? super T,? extends K> classifier, Collector<? super T,A,D> downstream) 返回一个并发 |
static <T,K,A,D,M extends ConcurrentMap<K,D>> | groupingByConcurrent(Function<? super T,? extends K> classifier, Supplier<M> mapFactory, Collector<? super T,A,D> downstream) 返回一个并发 |
static Collector<CharSequence,?,String> | joining() 返回一个 |
static Collector<CharSequence,?,String> | joining(CharSequence delimiter) 返回一个 |
static Collector<CharSequence,?,String> | joining(CharSequence delimiter, CharSequence prefix, CharSequence suffix) 返回一个 |
static <T,U,A,R> Collector<T,?,R> | mapping(Function<? super T,? extends U> mapper, Collector<? super U,A,R> downstream) 适应一个 |
static <T> Collector<T,?,Optional<T>> | maxBy(Comparator<? super T> comparator) 返回一个 |
static <T> Collector<T,?,Optional<T>> | minBy(Comparator<? super T> comparator) 返回一个 |
static <T> Collector<T,?,Map<Boolean,List<T>>> | partitioningBy(Predicate<? super T> predicate) 返回一个 |
static <T,D,A> Collector<T,?,Map<Boolean,D>> | partitioningBy(Predicate<? super T> predicate, Collector<? super T,A,D> downstream) 返回一个 |
static <T> Collector<T,?,Optional<T>> | reducing(BinaryOperator<T> op) 返回一个 |
static <T> Collector<T,?,T> | reducing(T identity, BinaryOperator<T> op) 返回 |
static <T,U> Collector<T,?,U> | reducing(U identity, Function<? super T,? extends U> mapper, BinaryOperator<U> op) 返回一个 |
static <T> Collector<T,?,DoubleSummaryStatistics> | summarizingDouble(ToDoubleFunction<? super T> mapper) 返回一个 |
static <T> Collector<T,?,IntSummaryStatistics> | summarizingInt(ToIntFunction<? super T> mapper) 返回一个 |
static <T> Collector<T,?,LongSummaryStatistics> | summarizingLong(ToLongFunction<? super T> mapper) 返回一个 |
static <T> Collector<T,?,Double> | summingDouble(ToDoubleFunction<? super T> mapper) 返回一个 |
static <T> Collector<T,?,Integer> | summingInt(ToIntFunction<? super T> mapper) 返回一个 |
static <T> Collector<T,?,Long> | summingLong(ToLongFunction<? super T> mapper) 返回一个 |
static <T,C extends Collection<T>> | toCollection(Supplier<C> collectionFactory) 返回一个 |
static <T,K,U> Collector<T,?,ConcurrentMap<K,U>> | toConcurrentMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper) 返回一个并发的 |
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) 返回一个并发的 |
static <T,K,U,M extends ConcurrentMap<K,U>> | toConcurrentMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier) 返回一个并发的 |
static <T> Collector<T,?,List<T>> | toList() 返回一个 |
static <T,K,U> Collector<T,?,Map<K,U>> | toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper) 返回一个 |
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) 返回一个 |
static <T,K,U,M extends Map<K,U>> | toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper, BinaryOperator<U> mergeFunction, Supplier<M> mapSupplier) 返回一个 |
static <T> Collector<T,?,Set<T>> | toSet() 返回一个 |
工作中应用:
注:这个项目微服务架构使用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.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);
// }
// }
// }
// }
// }
// }
}
转载于:https://blog.51cto.com/qinbin/2072310