【问题标题】:Getting element properties from first list item by getting element once vs couple of times performance通过获取元素一次与几次性能从第一个列表项获取元素属性
【发布时间】:2022-01-14 11:47:59
【问题描述】:

找不到任何关于此的文章。如果我们使用它有什么影响:

Fruit fruit = fruits.get(0);

FruitDto dto = new FruitDto();
dto.setPrice(fruit.getPrice());
dto.setType(fruit.getType());
... eg to set 10 properties using fruit.getSomeProperty

相比:

FruitDto dto = new FruitDto();
dto.setPrice(fruits.get(0).getPrice());
dto.setType(fruits.get(0).getType());
... eg to set 10 properties using fruits.get(0).getSomeProperty

如果我们使用fruits.stream().findFirst() 而不是get(0) 有什么好处吗?

【问题讨论】:

  • 性能差异可能很小,但由于第一个变体兼具可读性和潜在效率,为什么不直接使用它呢? fruits.stream().findFirst() 强制您在列表为空时处理可能不存在的值。但是当你知道列表不为空时,get(0) 显然更简单。甚至if(!fruits.isEmpty()) { … fruits.get(0) … } 也可能比引入 Stream 操作更简单。

标签: java collections java-stream


【解决方案1】:

是的,有些影响,但它可能可以忽略不计,具体取决于集合类型以及您实际上是在拉项目 0 还是更高的索引(不同的集合类型具有不同的 get 缩放比例,例如 get(0) 与 @987654323 LinkedList 上的 @ 在比较运行时会非常不同)。

我还要说,从清洁/维护 POV 来看,第一个版本更可取。考虑对某些属性集连续调用fruits.get(0).getProperty(),然后我们需要从第 0 项更改为第 1 项(例如,在许多地方需要更改为fruits.get(0).getProperty())。现在,这种更改会增加一些导致错误的拼写错误的风险(例如,有人错过了将 0 更改为 1)。

【讨论】:

    【解决方案2】:

    一般来说,与其说是性能,不如说是更简洁的代码风格,第一种方法可以很容易地提取到映射器方法中,将实体的属性复制到 DTO 中(实体属于某个集合实际上并不重要在某个索引处):

    FruitDto dto = toDto(fruits.get(0));
    
    static FruitDto toDto(Fruit fruit) {
        FruitDto dto = new FruitDto();
        dto.setPrice(fruit.getPrice());
        dto.setType(fruit.getType());
        // ...
        return dto;
    }
    

    关于使用Stream::findFirst 而不是检查列表的大小/空性——这也与代码样式和处理空输入集合有关:

    • “势在必行”
    if (fruits.isEmpty()) throw new NoFruitException(); // or return "empty" dto
    
    FruitDto dto = toDto(fruits.get(0));
    
    • “功能”使用Optional
    FruitDto dto = fruits.stream().findFirst() // Optional<Fruit>
        .map(Mapper::toDto)                    // Optional<FruitDto>
        .orElseThrow(NoFruitException::new);   // or .orElse(EMPTY_DTO)
    

    【讨论】:

    • 你也可以使用findFirst().orElseThrow(NoFruitException::new).toDto()
    • 这意味着toDto 方法在实体Fruit 类中实现。我认为应该是:Mapper.toDto(fruits.stream().findFirst().orElseThrow(NoFruitException::new))
    • 确实如此。对于静态方法,普通调用可能不太可读,除非它在同一个类中。我不太习惯为完全相同的事物拥有多个类并且需要将属性从一个复制到另一个的概念……
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-06
    • 2016-02-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-13
    相关资源
    最近更新 更多