java 如何使一个方法适合于实现接口的类?

ijnw1ujt  于 2023-02-15  发布在  Java
关注(0)|答案(1)|浏览(132)

我怎样才能使下面的方法适用于任何实现String getValue()接口的类?泛型可以做到吗?

private static void findUniqueEntriesInList(List<ColValueObject> list1, 
                                            List<ColValueObject> list2, 
                                            List<ColValueObject> result) {
    for (ColValueObject l1 : list1) {
      boolean found = false;
      for (ColValueObject l2 : list2) {
        if (l1.getValue().equals(l2.getValue())) {
          found = true;
          break;
        }
      }
      if (!found) {
        result.add(l1);
      }
    }
  }

与:

class ColValueObject implements GetValueToStringObject {
  private String base;
  private String value;
  // boilerplate omitted
}

我可以创建这个接口和方法:

public interface GetValueToStringObject {
  String getValue();
}

以及:

private static void findUniqueEntriesInListUsingGenerics(List<GetValueToStringObject> list1,
                                                           List<GetValueToStringObject> list2,
                                                           List<GetValueToStringObject> result) {
    for (GetValueToStringObject l1 : list1) {
      boolean found = false;
      for (GetValueToStringObject l2 : list2) {
        if (l1.getValue().equals(l2.getValue())) {
          found = true;
          break;
        }
      }
      if (!found) {
        result.add(l1);
      }
    }
  }

问题是我不能像这样直接调用这个方法:

findUniqueEntriesInListUsingGenerics(list1, list2, result);

2w2cym1i

2w2cym1i1#

我不太清楚您要实现什么,但很明显,List<GetValueToStringObject>不是List<ColValueObject>,反之亦然,并且由于GetValueToStringObjectColValueObject之间没有实现(或扩展)关系,因此您的方法无法正常工作。
做一些合理的假设,我认为您需要ColValueObject来实现GetValueToStringObject,然后您可以使用泛型和<T extends GetValueToStringObject>来完成您想要的任务:

class ColValueObject implements GetValueToStringObject {
  private String base;
  private String value;

  @Override
  public String getValue() {
    return value;
  }
  // boilerplate omitted
}

然后将方法实现为:

private static <T extends GetValueToStringObject> void findUniqueEntriesInListUsingGenerics(
    List<T> list1, List<T> list2, List<T> result) {
  for (T l1 : list1) {
    boolean found = false;
    for (T l2 : list2) {
      if (l1.getValue().equals(l2.getValue())) {
        found = true;
        break;
      }
    }
    if (!found) {
      result.add(l1);
    }
  }
}

这样,所有的列表都必须有相同的泛型类型,请参见答案的末尾,以获得更灵活的解决方案。
顺便说一句,我认为result参数不属于您的方法,它应该返回一个在方法中创建的List<T>

private static <T extends GetValueToStringObject> List<T> findUniqueEntriesInListUsingGenerics(
    List<T> list1, List<T> list2) {
  List<T> result = new ArrayList<>();
  // ... code above
  return result;
}

或者,如果希望list1list2result具有不同的类型,可以用途:

private static <T extends GetValueToStringObject> void findUniqueEntriesInListUsingGenerics(
        List<T> list1, 
        List<? extends GetValueToStringObject> list2, 
        List<? super T> result) {
    for (T l1 : list1) {
        boolean found = false;
        for (GetValueToStringObject l2 : list2) {
            if (l1.getValue().equals(l2.getValue())) {
                found = true;
                break;
            }
        }
        if (!found) {
            result.add(l1);
        }
    }
}

这里list1被定义为实际类型,list2可以是扩展(实现)GetValueToStringObject的任何类型列表,并且result可以是T的任何超类/超接口的列表。
例如,如果list1List<ColValueObject>,则result可以是List<ColValueObject>List<GetValueToStringObject>List<Object>,并且list2可以是List<GetValueToStringObject>List<ColValueObject>List<SomeOtherTypeImplementingGetValueToStringObject>
下面是另一个选项,但这将result的类型限制为仅List<GetValueToStringObjectList<Object>,我认为这比前面的解决方案用处更小:

private static  void findUniqueEntriesInListUsingGenerics(
        List<? extends GetValueToStringObject> list1, 
        List<? extends GetValueToStringObject> list2, 
        List<? super GetValueToStringObject> result) {
    for (GetValueToStringObject l1 : list1) {
        boolean found = false;
        for (GetValueToStringObject l2 : list2) {
            if (l1.getValue().equals(l2.getValue())) {
                found = true;
                break;
            }
        }
        if (!found) {
            result.add(l1);
        }
    }
}

相关问题