如何使用流

时间:2017-11-21 14:03:40

标签: xsd java-8 stream cxf

我认为一个非常简单的任务是使用Java 8流解析由soap webservice提供的嵌套对象。然而,当我考虑使用正确或最合适的方法时,我感到很困惑。我知道这将取决于环境,并且永远不会有简单的配方。我在过去两周一直在阅读在哪里以及如何使用流,但我无法就几个选项得出最终结论。如果我在处理肥皂客户端时根据非常常见的要求正确理解真正的应用程序,我会提出以下四种方法,如果有人能够提供技术意见,我会很感激。

我不喜欢像#34这样的简单回答;在这里我成功地这样做,所以你可以复制和粘贴类似的想法"。我真的很想知道我是否正确地应用了我到目前为止所阅读的内容。

首先,我的嵌套对象由Web服务回答:

//第一级

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "OndernemingAlgemeenType", propOrder = {
    "adressen",
    ... others properties
})
@XmlSeeAlso({
    Onderneming20Type.class
})
public class OndernemingAlgemeenType
{

    @XmlElement(name = "Adressen")
    protected AdresOndernemingLijstType adressen;
    ... others elements
}   

//返回列表的第二级

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "AdresOndernemingLijstType", propOrder = {
    "adres"
})
public class AdresOndernemingLijstType {

    @XmlElement(name = "Adres", required = true)
    protected List<AdresOndernemingType> adres; 
    ...
}

//第三级用于过滤列表并仅返回一个AdresOndernemingType

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "AdresOndernemingType", propOrder = {
    "type"
})
public class AdresOndernemingType
    extends AdresOndernemingBasisType{
    @XmlElement(name = "Type", required = true)
    protected TypeAdresOndernemingType type;
}

//第四级

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "AdresOndernemingBasisType", propOrder = {
   ... not relevant for this question
})
@XmlSeeAlso({
    AdresOndernemingType.class
})
public class AdresOndernemingBasisType
    extends AdresBasisType
{
       ... not relevant for this question
}

//第五级,最后是所需的字段(街道和城市)

@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "AdresBasisType", propOrder = {
    "straat", //street
    "gemeente" //city
})
@XmlSeeAlso({
    AdresOndernemingDeelnemingInType.class,
    AdresOndernemingBasisType.class
})
public class AdresBasisType {

    @XmlElement(name = "Straat")
    protected StraatRR20Type straat;
    @XmlElement(name = "Gemeente")
    protected GemeenteOptioneel20Type gemeente;

//了解其理解

方法1: 我明白这是null异常安全。 我的意思是,如果getAdressen或getAdres为null,则根本没有异常,也没有打印地址。

private void printOptionalDidactic(){
        Optional<AdresOndernemingLijstType> op = Optional.ofNullable(onderneming.getAdressen());
        op.map(AdresOndernemingLijstType::getAdres).get().stream().filter(Objects::nonNull)
        .filter(o -> "001".equals(o.getType().getCode().getValue().getValue()))
        .map(x -> System.out.println("My street is: ".concat(x.getStraat())));
}       

方法2: 假设永远不会有null元素(minOccurs =&#34; 1&#34;在xsd中为所有),因此使用Optional将毫无意义

private void printNoOptionalDidactic(){     
        onderneming.getAdressen().getAdres().stream()
        .filter(o -> "001".equals(o.getType().getCode().getValue().getValue()))
        .map(x -> System.out.println("My street is: ".concat(x.getStraat())));
}

方法3: 假设我想打印所有街道并且我不关心过滤,我知道在forEach之前使用flatMap没有任何优势 Replace nested loop with Java 8 flatmap

private void printForEachDidactic(){
        onderneming.getAdressen().getAdres().stream()
        .forEach(x -> System.out.println("My street is: ".concat(x.getStraat())));
}       

方法4 由于进程中使用的谓词和函数不使用共享资源, 我知道我可以使用并行性。尽管如此,只要数据很少,我就没有真正的收获 Should I always use a parallel stream when possible?

private void printParallelDidactic(){
        onderneming.getAdressen().getAdres().parallelStream()
        .filter(o -> "001".equals(o.getType().getCode().getValue().getValue()))
        .map(x -> System.out.println("My street is: ".concat(x.getStraat())));
}

1 个答案:

答案 0 :(得分:1)

如果您确实没有映射流的元素(例如,在方法1 map中),我将不会使用.map(x -> System.out.println...流方法。更好地调用forEach,它专门为流的每个元素执行代码。

关于你的第一种方法,我认为如果NoSuchElementException为空,则会抛出onderneming.getAdressen()。请参阅Optional.get

的实施
public T get() {
    if (value == null) {
        throw new NoSuchElementException("No value present");
    }
    return value;
}

否则,从代码的角度看,所有方法看起来都是有效的。当然,我对你的数据模型一无所知。

但是,您不需要仅仅因为Java 8引入它们而应用Java 8流和lambdas。例如,我不会在你的方法中使用流3.一个旧的循环学校也会这样做(在IMO中稍微更具可读性):

for (AdresOndernemingType x : onderneming.getAdressen().getAdres()) {
    System.out.println("My street is: ".concat(x.getStraat())));
}

关于并行流,我不会使用parallel(),除非我真的需要并行性来获得大数据集或长时间运行任务的性能。