将 Java final 关键字添加到在循环内构建实例的工作方法

采取以下 POJO:


public class Widget {

    private String fizz;

    private Long buzz;

    private List<Fidget> collaborators;


   // Constructor, getters & setters

}


public class Fidget {

    private String fizz;

    private String foo;


    // Constructor, getters & setters

}

以及以下(工作)方法:


public void compriseWidgets(List<Fidget> fidgetList) {

    List<Widget> widgets = new ArrayList<Widget>();

    Widget currentWidget = null;


    for (Fidget fidget : fidgetList) {

        if (currentWidget == null || 

                !currentWidget.getFizz().equals(fidget.getFizz())) {


            currentWidget = new Widget();

            widgets.add(currentWidget);

            currentWidget.setFizz(fidget.getFizz());

            currentWidget.setBuzz(fidget.getFoo().length());

        }


        currentWidget.getCollaborators().add(fidget);

    }


    return widgets;

}

在这里,我们只想返回一个List<Widget>并填充该列表:

  1. Fidget输入列表中的第一个开始(因此currentWidget == null);和

  2. 如果FidgetcurrentWidget具有相同的fizz

collaborators此外,currentWidget无论 fizzes 是否匹配,我们都希望继续追加。

我的问题

一个新的代码风格准则要求我们声明所有变量final...意味着我需要将上面的代码重构为如下所示:

public void compriseWidgets(final List<Fidget> fidgetList) {

    final List<Widget> widgets = new ArrayList<Widget>();

    final Widget currentWidget = null;


    for (final Fidget fidget : fidgetList) {

        ...

    }


    return widgets;

}

因为它既需要在循环Widget 内创建一个新的,又需要一个外部(循环外)对Widget我们可以添加的 a 的引用collaborators,所以我完全不知道如何用final. 有任何想法吗?另外,请注意,这不是我可以“推后”的,我只需要弄清楚它并让它与新的编码标准一起使用。


30秒到达战场
浏览 194回答 2
2回答

慕码人2483693

为了扩展我的评论,您可以或多或少地机械地转换您的示例代码,如下所示:public List<Widget> compriseWidgets(final List<Fidget> fidgetList) {&nbsp; &nbsp; final List<Widget> widgets = new ArrayList<Widget>();&nbsp; &nbsp; final Widget[] currentWidget = new Widget[] {null};&nbsp; &nbsp; for (final Fidget fidget : fidgetList) {&nbsp; &nbsp; &nbsp; &nbsp; if (currentWidget[0] == null ||&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; !currentWidget[0].getFizz().equals(fidget.getFizz())) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; currentWidget[0] = new Widget();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; widgets.add(currentWidget);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; currentWidget.setFizz(fidget.getFizz());&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; currentWidget.setBuzz(fidget.getFoo().length());&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; currentWidget.getCollaborators().add(fidget);&nbsp; &nbsp; }&nbsp; &nbsp; return widgets;}许多变量可以在final没有任何特殊影响的情况下生成,包括 Fidgets 和 Widgets 的列表,以及增强for循环中的循环变量。原始方法中唯一的其他变量是currentWidget,实现对其进行了修改。这可以用final长度为 1 的 ( ) 数组替换,然后可以将其第零个元素用作原始变量的直接替换。一个更麻烦的要求是您不能使用赋值语句(变量声明中的初始化程序不被视为“赋值”)。这正在推动一种更具功能性的编程风格,我想这可能是您的新指南的意图。然后,您可以像这样处理它:public List<Widget> compriseWidgets(final List<Fidget> fidgetList) {&nbsp; &nbsp; final List<Widget> widgets = new ArrayList<Widget>();&nbsp; &nbsp; final ListIterator<Fidget> fidgets = fidgetList.listIterator();&nbsp; &nbsp; while (addWidget(widgets, fidgets)) { /* empty */ }&nbsp; &nbsp; return widgets;}&nbsp; &nbsp;&nbsp;private boolean addWidget(final List<Widget> widgets, final ListIterator<Fidget> fidgets) {&nbsp; &nbsp; if (fidgets.hasNext()) {&nbsp; &nbsp; &nbsp; &nbsp; final Fidget firstFidget = fidgets.next();&nbsp; &nbsp; &nbsp; &nbsp; final Widget currentWidget = new Widget();&nbsp; &nbsp; &nbsp; &nbsp; widgets.add(currentWidget);&nbsp; &nbsp; &nbsp; &nbsp; currentWidget.setFizz(firstFidget.getFizz());&nbsp; &nbsp; &nbsp; &nbsp; currentWidget.setBuzz(firstFidget.getFoo().length());&nbsp; &nbsp; &nbsp; &nbsp; currentWidget.getCollaborators().add(firstFidget);&nbsp; &nbsp; &nbsp; &nbsp; while (fidgets.hasNext()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; final nextFidget = fidgets.next();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (currentWidget.getFizz().equals(nextFidget.getFizz())) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; currentWidget.getCollaborators().add(nextFidget);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; fidgets.previous();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; return false;}这几乎是相同的技巧,只是不太明显。可变状态隐藏在调用堆栈(每次调用addWidget()代表原始方法的突变currentWidget())和容器对象中,这次是 a ListIterator。人们可以在函数式编程方向上走得更远。例如,一般来说,您可以考虑基于流的方法,尽管我认为在这种特殊情况下,这并不是完全干净的。然而,更一般的函数式编程没有适用于 Streams 的约束。

白衣染霜花

Builder 设计模式是构建不可变对象的好方法。来源: https ://stackoverflow.com/a/15461337/4245294我喜欢这个设计模式的这个版本的地方在于它如何在创建对象之前为您提供验证规则的完美位置。应用于此问题的示例:public class Widget {&nbsp; &nbsp; private final String fizz;&nbsp; &nbsp; private final Long buzz;&nbsp; &nbsp; private final List<Fidget> collaborators;&nbsp; &nbsp; private Widget(Builder builder) {&nbsp; &nbsp; &nbsp; &nbsp; this.fizz = builder.fizz;&nbsp; &nbsp; &nbsp; &nbsp; this.buzz = builder.buzz;&nbsp; &nbsp; &nbsp; &nbsp; this.collaborators = builder.collaborators;&nbsp; &nbsp; }&nbsp; &nbsp; public static Builder builder() {&nbsp; &nbsp; &nbsp; &nbsp; return new Builder();&nbsp; &nbsp; }&nbsp; &nbsp; public static class Builder {&nbsp; &nbsp; &nbsp; &nbsp; private String fizz;&nbsp; &nbsp; &nbsp; &nbsp; private Long buzz;&nbsp; &nbsp; &nbsp; &nbsp; private List<Fidget> collaborators = new ArrayList<>();&nbsp; &nbsp; &nbsp; &nbsp; public Builder addFizz(String fizz) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.fizz = fizz;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public Builder addBuzz(Long buzz) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.buzz = buzz;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public Builder addCollaborators(List<Fidget> fidgets) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; collaborators.addAll(fidgets);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public Builder addCollaborator(Fidget fidget) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; collaborators.add(fidget);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return this;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; private void validate() throws InvalidArgumentException{&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ArrayList<String> invalidArguments = new ArrayList<>();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; boolean failedValidation = false;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (collaborators.isEmpty()) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; invalidArguments.add("collaborators");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; failedValidation = true;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (this.fizz == null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; invalidArguments.add("fizz");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; failedValidation = true;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (this.buzz == null) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; invalidArguments.add("buzz");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; failedValidation = true;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (failedValidation) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new InvalidArgumentException(invalidArguments.toArray(new String[0]));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public Widget build() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; validate();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new Widget(this);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}然后您创建一个有效的 Widget 对象,如下所示:Widget widget = Widget.builder().addFizz("test").addBuzz(999).addCollaborators(fidgets).build();您的compriseWidget方法存在我在对问题的评论中提到的问题,否则我也会为此提供一个示例。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java