Java方法参数中的通用集合

3
有没有办法在Java中实现这个功能?
 public static void change(List<? extends Object> list, int pos1, int pos2) {
  Object obj = list.get(pos1);
  list.set(pos1, list.get(pos2));
  list.set(pos2, obj);
 }

我成功避免警告和错误的唯一方法是这样的:
 public static <T> T change(List<T> list, int pos1, int pos2) {
  T obj = list.get(pos1);
  list.set(pos1, list.get(pos2));
  list.set(pos2, obj);
  return obj;
 }

但是我不喜欢被强制返回一个值。

3个回答

9

制作一个通用方法

public static <T> void change( List<T> list, int position1, int position2) {
    T obj = list.get(position1);
    list.set(position1, list.get(position2));
    list.set(position2, obj);
}

@辅助方法 我认为set方法不能使用通配符,因为列表的类型和插入的对象的类型都是未知的。 - josefx

8
java.util.Collections中,已经有一个swap(List<?> list, int i, int j)
这是OpenJDK源代码中的实现方式:
public static void swap(List<?> list, int i, int j) {
   final List l = list;
   l.set(i, l.set(j, l.get(i)));
}

有趣的是,它使用了原始的List类型来完成任务。该代码在编译时会生成警告,但据推测,@author Josh Bloch和Neal Gafter认为这是可以容忍的。


1
谢谢,我已经将@krosenvold的答案标记为已接受,因为它回答了问题,但我将使用Collections#swap,因为它已经实现了。 - Guido
有趣的实现方式...也很奇怪他们将列表标记为final。 - helpermethod
1
@辅助方法 - 你应该尽可能将所有内容标记为final。这样可以减少错误。如果你做得“正确”,你会发现大约90-95%的变量都可以被标记为final。Checkstyle和/或PMD有一个检查功能,可以告诉你是否有一些东西可以被标记为final,但实际上没有被标记。 - TofuBeer
我总是将成员变量标记为final,但从不将局部变量标记为final。我只是尝试使我的方法非常简短 :-). - helpermethod

2
使用捕获助手:
public static void change(List<?> list, int pos1, int pos2) {
    changePrivate(list, pos1, pos2);
}

public static <T> void change(List<T> list, int pos1, int pos2) {
    T obj = list.get(pos1);
    list.set(pos1, list.get(pos2));
    list.set(pos2, obj);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接