Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/369.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Lambda从列表中获取元素_Java_Lambda_Java 8_Java Stream - Fatal编程技术网

Java Lambda从列表中获取元素

Java Lambda从列表中获取元素,java,lambda,java-8,java-stream,Java,Lambda,Java 8,Java Stream,我有以下代码,它使用良好的旧java工作: List<Bar> repo = ArrayList<>(); public Bar foo(int id) { for(Bar c: repo){ if(c.getId() == id) return c; } Bar target = new Bar(); target.setFooo(""); target.setId(0); retu

我有以下代码,它使用良好的旧java工作:

List<Bar> repo = ArrayList<>();
public Bar foo(int id) {
    for(Bar c: repo){
        if(c.getId() == id)
            return c;
    }
    Bar target = new Bar();
    target.setFooo("");
    target.setId(0);
    return target;
}

但是上面的代码返回了一个
ArrayOutOfBounds
异常,我不确定如何返回(因为它是一个列表)或者为什么返回

如果您想使用函数式编程技术,最好重构代码,以便能够完全使用构造函数、生成器或工厂方法构造对象。setter是坏朋友,因为它们意味着可变性,而函数式编程就像是不可变的东西

因此,添加新的
Bar
构造函数:

public Bar(String fooo, int id) {
    this.fooo = fooo;
    this.id = id;
}
在此之后,您可能会意识到,所有
Bar
对象都可以在没有设置器的情况下使用。如果是这样,您只需删除setter并将
Bar
字段设置为final,这样
Bar
将变得不可变。即使您无法在其他地方摆脱setter,使用新的构造函数,您的
foo
方法也可以以更干净的方式重写:

public Bar foo(int id) {
    return repo.stream()
               .filter(c -> c.getId() == id)
               .findFirst()
               .orElseGet(() -> new Bar("", 0));
}

如果您想使用函数式编程技术,最好重构代码,以便能够完全使用构造函数、生成器或工厂方法构造对象。setter是坏朋友,因为它们意味着可变性,而函数式编程就像是不可变的东西

因此,添加新的
Bar
构造函数:

public Bar(String fooo, int id) {
    this.fooo = fooo;
    this.id = id;
}
在此之后,您可能会意识到,所有
Bar
对象都可以在没有设置器的情况下使用。如果是这样,您只需删除setter并将
Bar
字段设置为final,这样
Bar
将变得不可变。即使您无法在其他地方摆脱setter,使用新的构造函数,您的
foo
方法也可以以更干净的方式重写:

public Bar foo(int id) {
    return repo.stream()
               .filter(c -> c.getId() == id)
               .findFirst()
               .orElseGet(() -> new Bar("", 0));
}

您的解决方案与我的建议非常接近:

public Bar foo(int id) {
    return repo.stream()

      // find by id
      .filter(c -> c.getId() == id)

      // choose any
      .findAny()

      .orElseGet(() -> {
          target = new Bar(); 
          target.setFooo("");
          target.setId(0);
          return target;
      });
}
不要创建更复杂的构造函数。它们甚至经常被称为反模式。坚持你的二传手

如果要优化,请让设置器返回更新的对象。这种方法将允许在未来增加任意数量的二传手。看起来是这样的:

public Bar setFooo(String fooo) {
    this.fooo = fooo;
    return this; // return modified instance
}

// do the same for setId()
代码后面一点:

.orElseGet(() -> new Bar()
      .setFooo("")
      .setId(0)
      // add any number of future setters here
);

您的解决方案与我的建议非常接近:

public Bar foo(int id) {
    return repo.stream()

      // find by id
      .filter(c -> c.getId() == id)

      // choose any
      .findAny()

      .orElseGet(() -> {
          target = new Bar(); 
          target.setFooo("");
          target.setId(0);
          return target;
      });
}
不要创建更复杂的构造函数。它们甚至经常被称为反模式。坚持你的二传手

如果要优化,请让设置器返回更新的对象。这种方法将允许在未来增加任意数量的二传手。看起来是这样的:

public Bar setFooo(String fooo) {
    this.fooo = fooo;
    return this; // return modified instance
}

// do the same for setId()
代码后面一点:

.orElseGet(() -> new Bar()
      .setFooo("")
      .setId(0)
      // add any number of future setters here
);

据我所知,你的两个版本是相同的。我们需要知道更多的细节来说明导致异常的原因。上面的代码适合我。您可能在其他地方出错。最好删除
.orElse(null)
,更改为
可选目标,然后使用
if(bar.isPresent())返回bar.get()
,否则构造一个
条newTarget
——更好的是,使用
.orElseGet(()->{Bar newTarget=newbar();newTarget.setFooo(“”);newTarget.setId(0);return newTarget;})
我觉得第一个版本更好:)据我所知,您的两个版本是等效的。我们需要知道更多的细节来说明导致异常的原因。上面的代码适合我。您可能在其他地方出错。最好删除
.orElse(null)
,更改为
可选目标,然后使用
if(bar.isPresent())返回bar.get()
,否则构造一个
条newTarget
——更好的是,使用
.orElseGet(()->{Bar newTarget=newbar();newTarget.setFooo(“”);newTarget.setId(0);return newTarget;})
我觉得第一个版本更好:)