加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

Java:可以将通配符数组类型用作参数和返回类型吗?

发布时间:2020-12-15 04:30:13 所属栏目:Java 来源:网络整理
导读:例如,考虑一个函数,它接受String的ArrayList并将其拆分为String数组,并返回这些新数组的ArrayList: public static ArrayListString[] splitListIntoArrays(ArrayListString list,int divisor) { ArrayListString listSplit = new ArrayList(); ArrayListStr
例如,考虑一个函数,它接受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;
    }

有没有最好的方法可以避免代码重复?

解决方法

定义泛型方法似乎是最自然的方法:

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>与列表< 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,Long.class);
      split2.forEach(s -> java.lang.System.out.println(Arrays.toString(s)));
    }

输出:

[foo,bar]
[baz,foobar]
[barbaz]
[1,2]
[3,4]
[5]

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读