英文:
How can i reduce this repeat code in Java 8?
问题
我有以下的代码,它一直重复很多次。也许有一种方法可以减少它,但我不太了解Java。它看起来像这样:
public Optional<byte[]> generateReportA(List<ClassThatChange> request){
    if(CollectionUtils.isEmpty(request)) {
       return Optional.empty();
    }
    
    List<ClassThatNOChange> list = new ArrayList<>();
    
    for(ClassThatChange item : request){
        ClassThatNOChange c = new ClassThatNOChange()
        
        //这是从一个报告到另一个报告会改变的代码行
        c.setResult(callMethodA(item.getVariable1(), item.getVariable2()));
        list.add(c);
    }
    
    return Optional.of(callSameMethod(list));
}
public Optional<byte[]> generateReportB(List<ClassThatChange> request){
    if(CollectionUtils.isEmpty(request)) {
       return Optional.empty();
    }
    
    List<ClassThatNOChange> list = new ArrayList<>();
    
    for(ClassThatChange item : request){
        ClassThatNOChange c = new ClassThatNOChange()
        
        //这是从一个报告到另一个报告会改变的代码行
        c.setResult(callMethodB(item.getVariable2()));
        list.add(c);
    }
    
    return Optional.of(callSameMethod(list));
}
唯一会改变的是callMethodA、callMethodB等,但它们都返回相同类型的答案。
ClassThatChange 类似于这样:
public class Father{
      private Date date;
      // 然后是 getters 和 setters
}
public class Son extends Father{
      private String description;
      // 然后是 getters 和 setters
}
所有可以改变的类都扩展自Father。
有没有一种方法可以减少这种重复的代码?
对不起,我的英语不太好。
英文:
I have the following code that keeps repeating a lot. Maybe there is a way to reduce it but i dont know too much of java. It looks like this:
public Optional<byte[]> generateReportA(List<ClassThatChange> request){
        if(CollectionUtils.isEmpty(request)) {
		   return Optional.empty();
	    }
        
        List<ClassThatNOChange> list = new ArrayList<>();
        
        for(ClassThatChange item : request){
            ClassThatNOChange c = new ClassThatNOChange()
            
            //here is the line of code that changes from report to report
            c.setResult(callMethodA(item.getVariable1(), item.getVariable2()));
            list.add(c);
        }
        
        return Optional.of(callSameMethod(list));
}
public Optional<byte[]> generateReportB(List<ClassThatChange> request){
        if(CollectionUtils.isEmpty(request)) {
		   return Optional.empty();
	    }
        
        List<ClassThatNOChange> list = new ArrayList<>();
        
        for(ClassThatChange item : request){
            ClassThatNOChange c = new ClassThatNOChange()
            
            //here is the line of code that changes from report to report
            c.setResult(callMethodB(item.getVariable2()));
            list.add(c);
        }
        
        return Optional.of(callSameMethod(list));
}
The only thing that change is the callMethodA, or B, or C... but all of them return the same type of answer.
The ClassThatChange is something like this:
public class Father{
      private Date date;
      // then the getters and setters
}
public class Son extends Father{
      private String description;
      // then the getters and setters
}
All the classes that can change extends from the father.
Is there a way to reduce this repeat code?
Sorry for my bad English.
答案1
得分: 2
我认为你正在寻找的是一种方法,可以将每种情况中的类型转换为始终相同的类型。这可以通过Function或者你自己定义的自定义函数接口来实现。在这里,我展示了Function。
private <T> Optional<byte[]> convert(
    List<? extends T> request, 
    Function<? super T, ? extends SomeTypeYouDidNotShow> conversion) {
    if (request.isEmpty()) return Optional.empty();
    List<ClassThatNOChange> list = request.stream()
        .map(item -> {
                ClassThatNOChange c = new ClassThatNOChange();
                c.setResult(conversion.apply(item));
                return c;
            })
        .collect(Collectors.toList());
    return Optional.of(callSameMethod(list));
}
然后,你所有的重复方法都会类似于这样:
public Optional<byte[]> generateReportA(List<Father> request) {
    return convert(request, 
        item -> callMethodA(item.getVariable1(), item.getVariable2()));
}
public Optional<byte[]> generateReportB(List<Son> request) {
    return convert(request, 
        item -> callMethodB(item.getVariable2()));
}
英文:
I think what you are looking for is a way to plug in a conversion from the type that changes in each case to the type that is always the same. That could be done with a Function, or with a customized functional interface that you define. Here, I'm showing Function.
private <T> Optional<byte[]> convert(
    List<? extends T> request, 
    Function<? super T, ? extends SomeTypeYouDidNotShow> conversion) {
    if (request.isEmpty()) return Optional.empty();
    List<ClassThatNOChange> list = request.stream()
        .map(item -> {
                ClassThatNOChange c = new ClassThatNOChange();
                c.setResult(conversion.apply(item));
                return c;
            })
        .collect(Collectors.toList());
    return Optional.of(callSameMethod(list));
}
Then all your duplicate methods would look something like this:
public Optional<byte[]> generateReportA(List<Father> request) {
    return convert(request, 
        item -> callMethodA(item.getVariable1(), item.getVariable2()));
}
public Optional<byte[]> generateReportB(List<Son> request) {
    return convert(request, 
        item -> callMethodB(item.getVariable2()));
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论