如何重构逻辑相同的三个方法?

How to refactor three methods with the same logic?

这是我的方法:

    public List<Task> stopAndUpdateTasks(Map<Long, Future<Task>> futuresTask, List<Task> oldTasks, Map<Long, TaskStatus> oldTasksStatuses) {
        futuresTask.values().forEach(f -> f.cancel(false));
        final Map<Long, Task> tasksToUpdate = oldTasks.stream()
                .filter(task -> futuresTask.get(task.getId()).isCancelled())
                .peek(task -> task.setStatus(oldTasksStatuses.get(task.getId())))
                .collect(toMap(Task::getId, task -> task));
        log.info("Interrupted tasks ids:" + tasksToUpdate.keySet());
        return new ArrayList<>(tasksToUpdate.values());
    }

    public List<PayProcess> stopAndUpdateProcesses(Map<Long, Future<PayProcess>> futures, List<PayProcess> oldProcesses, Map<Long, ProcessingStatus> processesWithStatus) {
        futures.values().forEach(f -> f.cancel(false));
        final Map<Long, PayProcess> processesToUpdate = oldProcesses.stream()
                .filter(PayProcess -> futures.get(PayProcess.getId()).isCancelled())
                .peek(payProcess -> payProcess.setProcessingStatus(processesWithStatus.get(payProcess.getId())))
                .collect(toMap(PayProcess::getId, payProcess -> payProcess));
        log.info("Interrupted payments ids:" + processesToUpdate.keySet());
        return new ArrayList<>(processesToUpdate.values());
    }

    private List<Bundle> stopAndUpdateBundles(Map<Long, Future<Bundle>> futureBundles, List<Bundle> oldBundles, Map<Long, BundleStatus> oldBundleStatuses) {
        futureBundles.values().forEach(f -> f.cancel(false));
        final Map<Long, Bundle> bundlesToUpdate = oldBundles.stream()
                .filter(task -> futureBundles.get(task.getId()).isCancelled())
                .peek(bundle -> bundle.setStatus(oldBundleStatuses.get(bundle.getId())))
                .collect(toMap(Bundle::getId, bundle -> bundle));
        log.info("Interrupted bundles ids:" + bundlesToUpdate.keySet());
        return new ArrayList<>(bundlesToUpdate.values());
    }

你能建议我一些非常酷的方法来重构这些方法吗?我无法想象该怎么做,但我必须这样做。我尝试为实体编写泛型和接口,但它们不适用于 Future

这是我的解决方法:

如您所见 - 实体实现了所需的接口,但它不起作用

您可以通过这种方式完成(而不是使用通配符泛型)。注意 - 这假设 Task、Bundle 和 PayProcess 没有现有的公共超类。

创建抽象超类:

public abstract class CommonSuperClass<T>{

  private Long id;
  private T status;

  public Long getId() {
    return id;
  }

  public void setId(Long id) {
    this.id = id;
  }

  public T getStatus() {
    return status;
  }

  public void setStatus(T status) {
    this.status = status;
  }
}

现在让 Task 、PayProcess 和 Bundle 扩展它:

public class Task extends CommonSuperClass<TaskStatus>{
...
}
public class PayProcess extends CommonSuperClass<ProcessingStatus>{
...
}

现在像这样定义你的方法:

  public static <T extends CommonSuperClass<U>, U> List<T> stopAndUpdate(Map<Long, Future<T>> futures,
                                                                              List<T> oldList,
                                                                              Map<Long, U> oldStatuses) {
    futures.values().forEach(f -> f.cancel(false));
    final Map<Long, T> updates = oldList.stream()
        .filter(t -> futures.get(t.getId()).isCancelled())
        .peek(task -> task.setStatus(oldStatuses.get(task.getId())))
        .collect(toMap(t -> t.getId(), Function.identity()));
    //log.info("Interrupted tasks ids:" + tasksToUpdate.keySet());
    return new ArrayList(updates.values());
  }

有了这个你可以像这样使用:

    Map<Long, Future<Task>> futuresTask = new HashMap<>();
    List<Task> oldTasks = new ArrayList<>();
    Map<Long, TaskStatus> oldTasksStatuses = new HashMap<>();

    stopAndUpdate(futuresTask, oldTasks, oldTasksStatuses);

    Map<Long, Future<PayProcess>> futures = new HashMap<>();
    List<PayProcess> oldProcesses = new ArrayList<>();
    Map<Long, ProcessingStatus> processesWithStatus = new HashMap<>();

    stopAndUpdate(futures, oldProcesses, processesWithStatus);

只有当你已经有了这个关系时你才能这样做,或者你可以通过某种方式改变你的代码来做到这一点

private List<Item> stopAndUpdate(Map<Long, Future<Item>> futureItems, List<Item> oldItems, Map<Long, Status> oldStatuses) {
    futureItems.values().forEach(f -> f.cancel(false));
    final Map<Long, Item> itemsToUpdate = oldItems.stream()
            .filter(task -> futureItems.get(task.getId()).isCancelled())
            .peek(item -> item.setStatus(oldStatuses.get(item.getId())))
            .collect(toMap(Item::getId, item -> item));
    log.info("Interrupted bundles ids:" + itemsToUpdate.keySet());
    return new ArrayList<>(itemsToUpdate.values());
}

需要关系

interface Item {
    Long getId();
    void setStatus(Status status);
}

interface Status {

}

class Task implements Item {
    @Override
    public Long getId() {
        return null;
    }

    @Override
    public void setStatus(Status status) {

    }
}

class PayProcess implements Item {
    @Override
    public Long getId() {
        return null;
    }

    @Override
    public void setStatus(Status status) {

    }

    public void setProcessingStatus(Status status) {
    }
}

class Bundle implements Item {
    @Override
    public Long getId() {
        return null;
    }

    @Override
    public void setStatus(Status status) {

    }
}

class TaskStatus implements Status{}

class ProcessingStatus implements Status{}

class BundleStatus implements Status{}