例如,考虑一个函数,该函数接受String的ArrayList并将其拆分为String数组,并返回这些新数组的ArrayList:
public static ArrayList<String[]> splitListIntoArrays(ArrayList<String> list, int divisor) {
ArrayList<String> listSplit = new ArrayList<>();
ArrayList<String[]> listOfArrays = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
listSplit.add(list.get(i));
if ((listSplit.size() + divisor) % divisor == 0 || i == (list.size() - 1)) {
listOfArrays.add(listSplit.toArray(new String[listSplit.size()]));
listSplit = new ArrayList<>();
}
}
return listOfArrays;
}
现在,假设我想做同样的事情,但是对于Long的ArrayList:
public static ArrayList<Long[]> splitListIntoArrays(ArrayList<Long> list, int divisor) {
ArrayList<Long> listSplit = new ArrayList<>();
ArrayList<Long[]> listOfArrays = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
listSplit.add(list.get(i));
if ((listSplit.size() + divisor) % divisor == 0 || i == (list.size() - 1)) {
listOfArrays.add(listSplit.toArray(new Long[listSplit.size()]));
listSplit = new ArrayList<>();
}
}
return listOfArrays;
}
是否有最好的方法可以避免代码重复?
答案 0 :(得分:7)
定义通用方法似乎是最自然的方法:
public static <T> List<T[]> splitListIntoArrays(List<T> list, int divisor)
{
ArrayList<T> listSplit = new ArrayList<>();
ArrayList<T[]> listOfArrays = new ArrayList<>();
for (int i = 0; i < list.size(); i++)
{
listSplit.add(list.get(i));
if ((listSplit.size() + divisor) % divisor == 0 || i == (list.size() - 1))
{
listOfArrays.add(listSplit.toArray(new T[listSplit.size()]));
listSplit = new ArrayList<>();
}
}
return listOfArrays;
}
我将ArrayList<T>
替换为List<T>
界面,因为它更通用。
代码很好但是有一个问题:你不能创建一个通用数组,所以这个
new T[listSplit.size()]
不是有效的Java代码。
这些问题有多种解决方案,其中很多都依赖于反思。更好,最快的解决方案是将类直接传递给方法,以便您可以使用反射来实例化数组:
public static <T> List<T[]> splitListIntoArrays(List<T> list, int divisor, Class<T> clazz)
{
ArrayList<T> listSplit = new ArrayList<>();
ArrayList<T[]> listOfArrays = new ArrayList<>();
for (int i = 0; i < list.size(); i++)
{
listSplit.add(list.get(i));
if ((listSplit.size() + divisor) % divisor == 0 || i == (list.size() - 1))
{
@SuppressWarnings("unchecked")
T[] array = (T[]) java.lang.reflect.Array.newInstance(clazz, listSplit.size());
listOfArrays.add(listSplit.toArray(array));
listSplit = new ArrayList<>();
}
}
return listOfArrays;
}
以便现在可以使用:
static void test()
{
List<String> test = Arrays.asList("foo", "bar", "baz", "foobar", "barbaz");
List<String[]> split = splitListIntoArrays(test, 2, String.class);
split.forEach(s -> java.lang.System.out.println(Arrays.toString(s)));
List<Long> test2 = Arrays.asList(1L,2L,3L,4L,5L);
List<Long[]> split2 = splitListIntoArrays(test2, 2, Long.class);
split2.forEach(s -> java.lang.System.out.println(Arrays.toString(s)));
}
输出:
[foo, bar]
[baz, foobar]
[barbaz]
[1, 2]
[3, 4]
[5]