5

我正在做一些关于泛型编程的练习;有没有办法获取一个实现 List 的类并返回同一个类的反转版本?看起来这应该是可行的,因为至少从表面上看这个术语是“通用编程”。

也许通过执行就地反转?我也考虑过 Collections.reverse(),但它是一个 void 方法。

这是我的尝试和演示:

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Arrays;

public class ReverseDemo {

public static <T> List<T> reverse(List<T> list) {
    List<T> reversed = new ArrayList<T>();

    for (int i = list.size() - 1; i >= 0; i--) {
        reversed.add(list.get(i));
      }

    return reversed;
}

public static void main(String[] args) {
    LinkedList<Integer> linkedInt = new LinkedList<Integer>();
    ArrayList<Double> arrayDouble = new ArrayList<Double>();

    for (int k = 0; k < 10; k++) {
        double doubleNum = 10*Math.random();
        int intNum = (int) (10*Math.random());
        linkedInt.add(intNum);
        arrayDouble.add(doubleNum);
    }

    // LinkedList<Integer> demo
    System.out.println(Arrays.toString(linkedInt.toArray()));
    System.out.println(Arrays.toString(reverse(linkedInt).toArray()));
    System.out.println(reverse(linkedInt) instanceof LinkedList<?>);  // false

    // ArrayList<Double> demo
System.out.println(Arrays.toString(arrayDouble.toArray()));        
System.out.println(Arrays.toString(reverse(arrayDouble).toArray()));          
System.out.println(reverse(arrayDouble) instanceof ArrayList<?>);  // true
}
}

顺便说一句,这是我在这里的第一篇文章,有没有人知道直接从 Eclipse 发布代码同时保留间距和缩进的最佳方法?我使用了这里指定的四空格的方法,但是有点不一致。

4

7 回答 7

3

Guava 库有一个很好的、非破坏性的解决方案。请参阅Lists.reverse(List)

他们定义了一套ReverseList包装输入的类List。从那里开始,只需翻译所有调用(尽管“只是”可能有点低估了事情)。

于 2013-05-28T18:54:08.983 回答
2

如果要保留原始列表,可以尝试使用:

originalList.getClass().newInstance()

这不是一个 100% 正确的解决方案,因为如果原始类没有默认构造函数,它可能会抛出。但是,大多数集合都有创建空实例的默认构造函数。

于 2013-05-28T18:49:21.640 回答
2

尝试关注

public static <T> List<T> reverse(List<T> list) {

    List<T> reversed=null;
    try {
        reversed = list.getClass().newInstance();
        Collections.reverse(list);
        reversed.addAll(list);

    } catch (InstantiationException | IllegalAccessException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    };

     return reversed;
}
于 2013-05-28T18:58:06.210 回答
1

可能是无效的Collections.reverse(),但这只是因为您应该传入要反转的列表。

List<T> myList = ...;
Collections.reverse(myList);

您现在有一个反向列表。

于 2013-05-28T18:46:02.017 回答
1

的所有java.util实现List都是可克隆的,因此您可以使用它,但遗憾的是并非不求助于反射。在反射章节中,您还可以使用复制构造函数,它也被所有 Java 集合所支持。

不幸的是,没有完全通用的非破坏性反转方法。

另一方面,破坏性逆转太微不足道而没有趣味。

于 2013-05-28T18:48:43.930 回答
0

这似乎有效:

import java.util.*;

public class ReverseListDemo
{
  public static void main(String[] args)
  {
    List<String> original = Arrays.asList("A", "B", "C");
    List<String> reversal = reverse(original);

    System.out.println("Original: " + original);
    System.out.println("Reversal: " + reversal);
  }

  public static <T> List<T> reverse(List<T> list)
  {
    T[] objects = (T[]) list.toArray();
    List<T> copy = Arrays.asList(objects);
    Collections.reverse(copy);
    return copy;
  }
}
于 2013-05-28T19:49:12.793 回答
0

谢谢大家的回复。我写了一个方法 reverse2,它至少适用于实现类 ArrayList 和 LinkedList。不确定它的效率如何。

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Arrays;

// See http://stackoverflow.com/questions/16799066/return-reversed-generic-list-type-in-java.
public class ReverseDemo {

    public static <T> List<T> reverse1(List<T> list) {
        List<T> reversed = new ArrayList<T>();

        for (int i = list.size() - 1; i > -1; i--) {
            reversed.add(list.get(i));
          }

        return reversed;
    }

    public static <T> List<T> reverse2(List<T> list) {
        int size = list.size();

        ArrayList<T> obArray = new ArrayList<T>();
        obArray.addAll(list);

        ListIterator<T> iter = list.listIterator();  
        for (int i = 0; i < size; i++) {
            iter.next();
            iter.set(obArray.get(size - 1 - i));
        }       

        return list;
    }

    public static void main(String[] args) {
        LinkedList<Integer> linkedInt = new LinkedList<Integer>();
        ArrayList<Double> arrayDouble = new ArrayList<Double>();

        for (int k = 0; k < 10; k++) {
            double doubleNum = 10*Math.random();
            int intNum = (int) (10*Math.random());
            linkedInt.add(intNum);
            arrayDouble.add(doubleNum);
        }

        TextIO.putln("Testing reverse1.");

        // LinkedList<Integer> demo
        System.out.println(Arrays.toString(linkedInt.toArray()));
        System.out.println(Arrays.toString(reverse1(linkedInt).toArray()));
        TextIO.putln("LinkedList structure preserved?");
        System.out.println(reverse1(linkedInt) instanceof LinkedList<?>);

        // ArrayList<Double> demo
        System.out.println(Arrays.toString(arrayDouble.toArray()));
        System.out.println(Arrays.toString(reverse1(arrayDouble).toArray()));
        TextIO.putln("ArrayList structure preserved?");
        System.out.println(reverse1(arrayDouble) instanceof ArrayList<?>);

        TextIO.putln("\nTesting reverse2.");

        // LinkedList<Integer> demo
        System.out.println(Arrays.toString(linkedInt.toArray()));
        System.out.println(Arrays.toString(reverse2(linkedInt).toArray()));
        TextIO.putln("LinkedList structure preserved?");
        System.out.println(reverse2(linkedInt) instanceof LinkedList<?>);

        // ArrayList<Double> demo
        System.out.println(Arrays.toString(arrayDouble.toArray()));
        System.out.println(Arrays.toString(reverse2(arrayDouble).toArray()));
        TextIO.putln("ArrayList structure preserved?");
        System.out.println(reverse2(arrayDouble) instanceof ArrayList<?>);
    }

}

控制台输出:

反向测试1。[8, 0, 1, 9, 3, 4, 3, 7, 6, 3] [3, 6, 7, 3, 4, 3, 9, 1, 0, 8] LinkedList结构保留了吗?false [8.301783107294664, 5.434068303620735, 9.095396759542615, 0.41823972682620836, 9.56659902304762, 3.2560723280079085, 4.037362000077436, 9.731919590391389, 0.5243645318825874, 5.9432185528462975] [5.9432185528462975, 0.5243645318825874, 9.731919590391389, 4.037362000077436, 3.2560723280079085, 9.56659902304762, 0.41823972682620836, 9.095396759542615, 5.434068303620735, 8.301783107294664] ArrayList structure preserved? 真的

反向测试2。[8, 0, 1, 9, 3, 4, 3, 7, 6, 3] [3, 6, 7, 3, 4, 3, 9, 1, 0, 8] LinkedList结构保留了吗?true [8.301783107294664, 5.434068303620735, 9.095396759542615, 0.41823972682620836, 9.56659902304762, 3.2560723280079085, 4.037362000077436, 9.731919590391389, 0.5243645318825874, 5.9432185528462975] [5.9432185528462975, 0.5243645318825874, 9.731919590391389, 4.037362000077436, 3.2560723280079085, 9.56659902304762, 0.41823972682620836, 9.095396759542615, 5.434068303620735, 8.301783107294664] ArrayList structure preserved? 真的

于 2013-05-29T00:05:11.563 回答