Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用泛型<;K>;减少重复代码?_Java_Oop_Generics_Inheritance - Fatal编程技术网

Java 使用泛型<;K>;减少重复代码?

Java 使用泛型<;K>;减少重复代码?,java,oop,generics,inheritance,Java,Oop,Generics,Inheritance,我有下面的代码。正如你们所看到的,我正在执行类似的逻辑,但一次用于自行车,一次用于汽车。我可以使用来减少重复的代码吗?我没有使用,因此我不确定在何处以及如何将其合并。在哪里可以决定是调用getCarsWithFeature还是getBikesWithFeature 减少行数(可能会降低可读性)或使用类似的重复代码是最佳做法吗 public Set<Car> getPremiumCars(String filter) { final Callable<Set<Car

我有下面的代码。正如你们所看到的,我正在执行类似的逻辑,但一次用于自行车,一次用于汽车。我可以使用
来减少重复的代码吗?我没有使用
,因此我不确定在何处以及如何将其合并。在哪里可以决定是调用
getCarsWithFeature
还是
getBikesWithFeature

减少行数(可能会降低可读性)或使用类似的重复代码是最佳做法吗

public Set<Car> getPremiumCars(String filter) {
    final Callable<Set<Car>> retryGetCars = new RetryingCallable<>(retryStrategy(), getCars(filter));  
    return retryGetCars.call();
}

public Callable<Set<Car>> getCars(String feature) {
    return new Callable<Set<Car>>() {
        @Override
        public Set<Car> call() throws Exception {
            Set<Car> cars = getCarsWithFeature(feature); 
            return Collections.unmodifiableSet(cars);
        }
    };
}

public Set<Bike> getPremiumBikes(String filter) {
    final Callable<Set<Bike>> retryGetBikes = new RetryingCallable<>(retryStrategy(), getBikes(filter));
    return retryGetBikes.call();            
}

public Callable<Set<Bike>> getBikes(String feature) {
    return new Callable<Set<Bike>>() {
        @Override
        public Set<Bike> call() throws Exception {
            Set<Bike> bikes = getBikesWithFeature(feature); 
            return Collections.unmodifiableSet(bikes);
        }
    };
}
public Set getPremiumCars(字符串过滤器){
final Callable retryGetCars=new RetryingCallable(retryStrategy(),getCars(filter));
return retryGetCars.call();
}
公共可调用getCars(字符串功能){
返回新的可调用(){
@凌驾
public Set call()引发异常{
设置车辆=getCarsWithFeature(特征);
返回集合。不可修改集合(cars);
}
};
}
公共集getPremiumBikes(字符串筛选器){
final Callable retryGetBikes=new RetryingCallable(retryStrategy(),getBikes(filter));
return retryGetBikes.call();
}
公共可调用getBikes(字符串特性){
返回新的可调用(){
@凌驾
public Set call()引发异常{
设置bikes=getBikesWithFeature(feature);
返回集合。不可修改集合(自行车);
}
};
}

创建Car和Bike的基类,然后将通用方法放在那里。 然后将汽车和自行车从中伸出。使用基类更新公共方法。下面给出了实施的示例提示:

class Vehicle {
  public Set<Vehicle> getWithFilter(String filter) {
    final Callable<Set<Vehicle>> retryGet = new RetryingCallable<>(retryStrategy(), get(filter));
    return retryGet.call();            
  }
  public Callable<Set<Vehicle>> getWithFeature(String feature) {
    return new Callable<Set<Vehicle>>() {
        public Set<Vehicle> call() throws Exception {
            Set<Vehicle> vehicles = getWithFeature(feature); 
            return Collections.unmodifiableSet(vehicles);
        }
    };
  }

} 
class Car extends Vehicle {
}
class Bike extends Vehicle {
}

我不知道您的全部代码,但我建议这两个类实现相同的接口-比方说
车辆

  public interface Vehicle {
  }
然后,您可以编写最近可以重用的代码:

  public <T extends Vehicle> Set<T> getPremiumVehicle(Function<String, Callable<Set<T>>> vehicleSupplier, String filter) throws Exception {
    final Callable<Set<T>> retryGetCars = new RetryingCallable<T>(retryStrategy(), vehicleSupplier.apply(filter));
    return retryGetCars.call();
  }

  public <T extends Vehicle> Callable<Set<T>> getVehicle(Function<String, Set<T>> vehicleSupplier, String feature) {
    return () -> {
      Set<T> vehicles = vehicleSupplier.apply(feature);
      return Collections.unmodifiableSet(vehicles);
    };
  }
public Set getPremiumVehicle(函数vehicleSupplier,字符串过滤器)引发异常{
final Callable retryGetCars=新的RetryingCallable(retryStrategy(),Vehicles Supplier.apply(filter));
return retryGetCars.call();
}
公共可调用getVehicle(功能车辆供应商,字符串功能){
返回()->{
设置车辆=车辆供应商。应用(功能);
返回集合。不可修改集合(车辆);
};
}
现在,您可以重用上述代码,如:

  public Set<Car> getPremiumCars(String filter) throws Exception {
    return getPremiumVehicle(this::getCars, filter);
  }

  public Set<Bike> getPremiumBikes(String filter) throws Exception {
    return getPremiumVehicle(this::getBikes, filter);
  }

  public Callable<Set<Car>> getCars(String feature) {
    return getVehicle(this::getCarsWithFeature, feature);
  }

  public Callable<Set<Bike>> getBikes(String feature) {
    return getVehicle(this::getBikesWithFeature, feature);
  }
公共集getPremiumCars(字符串筛选器)引发异常{
返回getPremiumVehicle(this::getCars,filter);
}
公共集getPremiumBikes(字符串筛选器)引发异常{
返回getPremiumVehicle(this::getBikes,filter);
}
公共可调用getCars(字符串功能){
返回getVehicle(此::getCarsWithFeature,feature);
}
公共可调用getBikes(字符串特性){
返回getVehicle(此::getBikesWithFeature,feature);
}

是的,如果您对汽车和自行车都有一个通用(基类)类型,您可以这样做。但是,汽车和自行车的类型完全不同,我想您会在使用泛型时遇到麻烦。最好将所有通用代码都分解成一个抽象基类,因为这样仍然可以让您专门化自行车或汽车子类的任何代码需求。这个问题的答案应该是
getCarsWithFeature
getBikesWithFeature
。无论是否使用仿制药,它们似乎都是不同的调用。谢谢@Piro。是的,他们确实是不同的电话。在这种情况下不可能使用泛型吗?为什么代码中充斥着
Callables
和其他不相关的东西?既然你在基本代码方面遇到了问题,你应该坚持使用基本代码,而不是无缘无故地让它看起来“高级”。谢谢你的回答。正如@Piro在上面的评论中提到的,有两个不同的调用
getCarsWithFeature
getBikesWithFeature
。即使有一个基类,那部分代码仍然必须存在。你认为我能转到基础课的哪一部分?谢谢你的回答。我要试一试。但是,如果我没有汽车和自行车,而是上完全不相关的课呢?在这种情况下,我不能有一个基类。在这种情况下,建议是什么?在这种情况下,您必须使用通用模板或Java对象类,然后转换到适当的类。是的,这也是我的想法。所以我的问题是关于泛型。我不能使用基类方法。让我们来。
  public Set<Car> getPremiumCars(String filter) throws Exception {
    return getPremiumVehicle(this::getCars, filter);
  }

  public Set<Bike> getPremiumBikes(String filter) throws Exception {
    return getPremiumVehicle(this::getBikes, filter);
  }

  public Callable<Set<Car>> getCars(String feature) {
    return getVehicle(this::getCarsWithFeature, feature);
  }

  public Callable<Set<Bike>> getBikes(String feature) {
    return getVehicle(this::getBikesWithFeature, feature);
  }