【问题标题】:Converting code in Java 8 streams在 Java 8 流中转换代码
【发布时间】:2017-12-08 15:45:33
【问题描述】:

是否有任何简单的方法可以使用流和 forEach 将此代码转换为 java 8。

List<List<IStitchable>> listOfEnvelopes = new ArrayList<>();
List<IStitchable> statementsInEnvelope = new ArrayList<>();
int totalPages = 0;

for(byte[] byteArray :byteArrays){
    totalPages = totalPages + getPagesInDocument(byteArray);

    if(totalPages/2>MAX_SHEETS_FOR_OVERSIZE_ENVELOPE){
        totalPages = 0;
        listOfEnvelopes.add(statementsInEnvelope);
        tatementsInEnvelope = new ArrayList<IStitchable>();
    }

    statementsInEnvelope.add(createStitchableFromSnapshot(byteArray));
} 

我试图做类似的事情

byteArrays.stream().forEach(byteArray->{
    totalPages = totalPages + getPagesInDocument(byteArray);            
    if(totalPages/2>MAX_SHEETS_FOR_OVERSIZE_ENVELOPE){
        totalPages = 0;
        listOfEnvelopes.add(statementsInEnvelope);
        statementsInEnvelope = new ArrayList<IStitchable>();
    }
    statementsInEnvelope.add(createStitchableFromSnapshot(byteArray));
});

但是我不能在 ForEach 中使用 totalPagesstatementsInEnvelope, 无法从 forEach 范围访问它们
最后有没有更简洁的方法来重构这个东西。任何想法将不胜感激。

【问题讨论】:

  • 我在质疑生成的代码是否比前一个更好。对可读性的影响是有争议的。此外,现在您正在为使用 AtomicInteger 付出代价(额外分配、堆中的额外指针取消引用、读取和更新 volatile 字段)
  • 这里“最简单”的事情是旋转一个自定义收集器,编写它并不复杂,这里有一个参考,例如:stackoverflow.com/questions/47645399/…

标签: java java-8 coding-style refactoring


【解决方案1】:

最简单的解决方案是使用AtomicInteger

List<List<IStitchable>> listOfEnvelopes = new ArrayList<>();     
List<IStitchable> statementsInEnvelope = new ArrayList<>();
AtomicInteger totalPages = new AtomicInteger();

byteArrays.stream().forEach(byteArray -> {
  totalPages.addAndGet(getPagesInDocument(byteArray));

  if(totalPages.get() / 2 > MAX_SHEETS_FOR_OVERSIZE_ENVELOPE){
    totalPages.set(0);
    listOfEnvelopes.add(new ArrayList<>(statementsInEnvelope));
    statementsInEnvelope.clear();
  }
  statementsInEnvelope.add(createStitchableFromSnapshot(byteArray));
});

【讨论】:

  • 但即使这样也不能解决在 forEach 中访问 statementsInEnvelope 的问题。它在 forEach 的范围之外声明。
  • make statementsInEnvelope final?
  • 是的,它确实解决了它。请注意,我将分配更改为clear()
  • @AdamSiemion 我认为您可以在这里使用具有单个元素的数组而不是 AtomicInteger,对于这类问题来说,它的成本太高了
  • @AdamSiemion 更不用说forEach 更新了文档明确禁止的外部集合。最干净的方法是旋转自定义收集器,例如:stackoverflow.com/questions/47645399/…
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-08-16
  • 1970-01-01
  • 2014-04-26
  • 1970-01-01
  • 2018-08-11
  • 1970-01-01
  • 2016-03-13
相关资源
最近更新 更多