Java8新特性-官方庫新特性
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.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新特性-官方庫新特性