当前位置: 首页 > 面试题库 >

我应该扩展ArrayList来添加不为null的属性吗?

益泰平
2023-03-14
问题内容

我想将对象集合添加到arrayList,仅当特定属性不为null时。

我正在考虑扩展ArrayList并在子类中实现检查。

一种替代方法是在将属性放入Arraylist中之前检查属性,但这意味着,如果我需要根据逻辑将对象添加到arraylist中,则我将不得不分散if检查每个位置。

我想知道您对此有何想法……再想一想,这是否太过分了?


问题答案:

实际上,我建议ArrayList使用记录良好的
Decorator

模式包装。您只需ArrayList用另一个List实现来包装您的方法,该实现委派大多数方法,但添加验证逻辑:

public class ValidatingListDecorator extends AbstractList<MyBusinessObject>
{

    private final List<MyBusinessObject> target;

    public ValidatingListDecorator(List<MyBusinessObject> target) {
        this.target = target;
    }

    @Override
    public MyBusinessObject set(int index, MyBusinessObject element)
    {
        validate(element);
        return target.set(index, element);
    }

    @Override
    public boolean add(MyBusinessObject o)
    {
        validate(o);
        return target.add(o);
    }

    //few more to implement

}

优点:

  • 您仍然可以根据需要访问原始列表,而无需验证(但是您可以限制它)
  • 轻松堆叠不同的验证,可以有选择地打开和关闭它们。
  • @helios 所述,促进对继承的 合成
  • 提高可测试性
  • 不需要将您绑定到特定的List实现上,您可以向Hibernate支持的持久性列表LinkedList或Hibernate支持的持久性列表中添加验证。您甚至可以考虑使用通用Collection装饰器来验证任何集合

实施说明

尽管实施记得有相当多的方法,你必须要记住,同时覆盖:add()addAll()set()subList()(?),等等。

此外,您的对象必须是不可变的,否则用户可以添加/设置有效对象,然后对其进行修改以违反合同。

好的OO设计

最后我写了:

validate(element)

但请考虑:

element.validate()

这是一个更好的设计。

堆叠验证

如前所述,如果要堆叠验证,在单个单独的类中验证每个属性/认识,请考虑以下惯用法:

public abstract class ValidatingListDecorator extends AbstractList<MyBusinessObject>
{

    private final List<MyBusinessObject> target;

    public ValidatingListDecorator(List<MyBusinessObject> target) {
        this.target = target;
    }

    @Override
    public MyBusinessObject set(int index, MyBusinessObject element)
    {
        validate(element);
        return target.set(index, element);
    }

    protected abstract void validate(MyBusinessObject element);

}

…以及一些实现:

class FooValidatingDecorator extends ValidatingListDecorator {

    public FooValidatingDecorator(List<MyBusinessObject> target)
    {
        super(target);
    }

    @Override
    protected void validate(MyBusinessObject element)
    {
        //throw if "foo" not met
    }
}

class BarValidatingDecorator extends ValidatingListDecorator {

    public BarValidatingDecorator(List<MyBusinessObject> target)
    {
        super(target);
    }

    @Override
    protected void validate(MyBusinessObject element)
    {
        //throw if "bar" not met
    }
}

是否只想验证 foo

List<MyBusinessObject> list = new FooValidatingDecorator(rawArrayList);

要同时验证 foobar 吗?

List<MyBusinessObject> list = 
  new BarValidatingDecorator(new FooValidatingDecorator(rawArrayList));


 类似资料:
  • 我在我的组件中接收道具。我想在此组件中添加一个带有道具的属性“LegendPosition”。我不能那样做。请帮我做这个。我已经尝试过此代码,但没有成功:

  • 如果作为参数输入,则不应该将其添加到arrayList中,我正在使用BlueJ编译器,并且我已经尝试了几种方法对其进行编码,但仍然无效。 下面是我的方法: 还试过这样的办法: 也试过这个: 并尝试了这个: 我相信我已经用尽了我能想到的所有方法,并在网上做了研究,但似乎不能找到一个有效的答案,我的问题。上面的方法要么添加null,要么不添加null并且不添加非null的新car参数。似乎不知道如何不

  • 问题内容: 我需要知道是否有可能通过扩展将某些属性和行为添加到某些POJO JPA实体(使用 hibernate 提供程序),然后使EntityManager返回扩展对象而不是仅返回pojo实体,如以下示例: POJO JPA实体类 扩展类 获取扩展类的对象 我评估的另一种可能的方法是使用复合实体扩展功能,并委派所有设​​置方法和获取方法,但这可能意味着需要处理大量表: 任何建议将不胜感激。 问题

  • 我扩展了JavaFX按钮,如下所示: 现在我希望能够在我的FXML中使用它。大概是这样的: 我如何做到这一点。

  • 问题内容: 我正在制作一个维护数字列表的简单程序,并且我希望该列表也有一个名称。最好的方法是:让我的列表类扩展ArrayList或使其包含ArrayList成员?在两种情况下,当然都会有一个“名称”字符串成员。 第一种方法意味着我只需要实现名称的getter和setter方法,但是我认为这会使我的课程与特定实现紧密联系在一起吗?例如,如果我以后要使用Vector,则到处都必须更改代码。 第二种方法

  • 根据这些答案中的建议:对于laravel 4助手或基本功能,什么是最佳实践和最佳场所? 我已经创建了一个文件并将其添加到应用程序中。我的类应该扩展什么,如何在控制器中引用它? 我尝试在控制器中这样引用它: 但我得到控制器的方法没有找到。