[英]Return reversed generic list-type in Java
我正在做一些關於泛型編程的練習; 有沒有辦法獲取一個實現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發布代碼同時保留間距和縮進的最佳方法? 我已經使用了這里指定的四空格法,但它有點不一致。
Guava庫有一個很好的,非破壞性的解決方案。 請參閱Lists.reverse(列表) 。
它們定義了一組包裝輸入List
的ReverseList
類。 從那里開始,只需要翻譯所有的電話(雖然“只是”可能會略微低估一些事情)。
如果要保留原始列表,可以嘗試使用:
originalList.getClass().newInstance()
這不是100%正確的解決方案,因為如果原始類沒有默認構造函數,它可能會拋出。 但是,大多數集合都具有創建空實例的默認構造函數。
嘗試下面
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;
}
Collections.reverse()
可能是無效的,但這只是因為你應該傳入List來反轉。
List<T> myList = ...;
Collections.reverse(myList);
你現在有一個反向列表。
List
所有java.util
實現都是可復制的,所以你可以使用它,但遺憾的是沒有求助於反射。 在反思章節中,您還可以使用復制構造函數,該構造函數也適用於所有Java集合。
遺憾的是,沒有完全通用的非破壞性逆轉方法。
另一方面,破壞性逆轉太微不足道了。
這似乎有效:
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;
}
}
感謝大家的回復。 我寫了一個方法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<?>);
}
}
控制台輸出:
測試reverse1。 [8,0,1,9,3,4,3,7,6,3] [3,6,7,3,4,3,9,1,0,8] LinkedList結構保留了嗎? 假[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的結構保留下來? 真正
測試reverse2。 [8,0,1,9,3,4,3,7,6,3] [3,6,7,3,4,3,9,1,0,8] LinkedList結構保留了嗎? 真[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的結構保留下來? 真正
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.