繁体   English   中英

Java泛型,将嵌套列表转换为嵌套数组

[英]Java generics, convert nested list to nested array

我必须接口到一些使用嵌套数组的旧代码,因此必须将嵌套列表转换为嵌套数组。

我以为自己应该已经在某些现有库中实现了此功能。 我在Google / StackOverflow上进行了搜索,但没有发现任何问题。 我检查了Apache Commons和Guava,但没有找到等效的功能。

这是我的代码,我担心的是,这可以通过更简单的方式完成。 任何想法,建议,改进都将受到热烈欢迎。

@SuppressWarnings("rawtypes")
public static <E> Class getNestedListClass(List<List<E>> list){
    if (list == null) {
        return null;
    }

    for (final List<E> innerList: list) {
        if (innerList == null || innerList.isEmpty()) {
            continue;
        }
        return innerList.get(0).getClass();
    }
    return null;
}

@SuppressWarnings({ "unchecked", "rawtypes" })
public static <E> E[][] convertNestedList(List<List<E>> list){
    final Class<?> clazz = getNestedListClass(list);
    if (clazz == null) {
        return null;
    }
    final E[][] result = (E[][]) Array.newInstance(clazz, list.size(), 0);

    for (int i = 0; i < list.size(); i++) {    
        final List<E> innerList = list.get(i);
        if (innerList == null) {
            continue;
        }
        result[i] = innerList.toArray((E[]) Array.newInstance(clazz, innerList.size()));
    }
    return result;
}


@Test
public void testConvertNestedList() {
    final List<List<String>> list = new ArrayList<List<String>>();
    list.add(new ArrayList<String>());
    list.get(list.size() - 1).add("0.0");
    list.get(list.size() - 1).add("0.1");
    list.get(list.size() - 1).add("0.2");
    list.add(new ArrayList<String>());
    list.get(list.size() - 1).add("1.0");
    list.get(list.size() - 1).add("1.1");
    list.get(list.size() - 1).add("1.2");
    list.get(list.size() - 1).add("1.3");
    list.add(new ArrayList<String>());
    list.get(list.size() - 1).add("2.0");
    list.get(list.size() - 1).add("2.1");

    final String[][] array = convertNestedList(list);

    final String[][] expected = new String[][] { 
            { "0.0", "0.1", "0.2" }, 
            { "1.0", "1.1", "1.2", "1.3" },
            { "2.0", "2.1" } };
    assertArrayEquals(expected, array);

}

EDIT添加了一些测试用例:

@Test
public void testConvertNestedListCaseNull() throws NetLineMarketException {
    List<List<Object>> list = null;
    Object[][] array = ArrayUtils.convertNestedList(list);
    Object[][] expected = null;
    assertArrayEquals(expected, array);
}

@Test
public void testConvertNestedListCaseNullElement() throws NetLineMarketException {
    List<List<Object>> list = new ArrayList<List<Object>>();
    list.add(null);
    Object[][] array = ArrayUtils.convertNestedList(list);
    Object[][] expected = new Object[][] { null };
    assertArrayEquals(expected, array);
}

@Test
public void testConvertNestedListCaseNullElement2() throws NetLineMarketException {
    List<List<Object>> list = new ArrayList<List<Object>>();
    list.add(new ArrayList<Object>());
    list.get(0).add(null);
    Object[][] array = ArrayUtils.convertNestedList(list);
    Object[][] expected = new Object[][] { { null } };
    assertArrayEquals(expected, array);
}

@Test
public void testConvertNestedListCaseEmpty() throws NetLineMarketException {
    List<List<Object>> list = new ArrayList<List<Object>>();
    Object[][] array = ArrayUtils.convertNestedList(list);
    Object[][] expected = new Object[][] { };
    assertArrayEquals(expected, array);
}

@Test
public void testConvertNestedListCaseString() throws NetLineMarketException {
    final String string = "string";
    List<List<Object>> list = new ArrayList<List<Object>>();
    list.add(new ArrayList<Object>());
    list.get(0).add(string);
    Object[][] array = ArrayUtils.convertNestedList(list);
    Object[][] expected = new Object[][] { { string } };
    assertArrayEquals(expected, array);
}

@Test(expected=MyException.class)
public void testConvertNestedListCaseMix() throws NetLineMarketException {
    final String string = "string";
    List<List<Object>> list = new ArrayList<List<Object>>();
    list.add(new ArrayList<Object>());
    list.get(0).add(string);
    list.get(0).add(Boolean.TRUE);
    Object[][] array = ArrayUtils.convertNestedList(list);
}

您的代码存在一些问题。 例如:

  • List<Object>(null)转换为null而不是Object[] { null }
  • List<Object>("string")转换为String[] { "string" }而不是Object[] { "string" }
  • List<Object>("string", Boolean.TRUE)产生运行时错误。

我的建议:

public static <T> T[][] toArray(List<List<T>> list, Class<T> clazz) {
    if (list == null) {
        return null;
    }
    List<T[]> temp = new ArrayList<>();
    @SuppressWarnings("unchecked")
    T[] inner = (T[]) Array.newInstance(clazz, 0);
    for (List<T> sublist : list) {
        temp.add(sublist == null ? null : sublist.toArray(inner));
    }
    @SuppressWarnings("unchecked")
    T[][] outer = (T[][]) Array.newInstance(inner.getClass(), temp.size());
    return temp.toArray(outer);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM