如何将嵌套的对象数组类型转换为嵌套的字符串列表

How to type-cast a nested Array of Objects into a nested List of Strings

无法从 Java

中的数组创建嵌套的 ArrayList

我正在尝试从数组创建嵌套列表。

但是我在将 Object 转换为 String 时遇到问题:

Object[] array = new Object[] {
                    new String[] {"add, hack"},
                    new String[] {"add, hackerrank"},
                    new String[] {"find, hac"},
                    new String[] {"find, hak"}
};

List<List<String>> list = Arrays.asList(Arrays.asList((array.toString())));

那么,我该如何正确转换呢?


这里是保留List<List<String>>的方法:

public static List<Integer> contacts(List<List<String>> queries) {
    for (List<String> query : queries) {
        String operation = query.get(0); // --> gives "add, hack" (I expect "add")
        String word = query.get(1);
    }
}

您可以 stream 数组,然后收集到 List:

Object[] array = new Object[] {
            new String[] {"add, hack"},
            new String[] {"add, hackerrank"},
            new String[] {"find, hac"},
            new String[] {"find, hak"}};

List<List<String>> list = Arrays.stream(array)
        .map(String[].class::cast)
        .map(arr -> arr[0].split(", "))
        .map(Arrays::asList)
        .collect(Collectors.toList());
    
System.out.println(list);

输出:

[[add, hack], [add, hackerrank], [find, hac], [find, hak]]

使用 JDK 16+ 你可以:

List<List<String>> list = Arrays.stream(array)
        .map(String[].class::cast)
        .map(arr -> arr[0].split(", "))
        .map(Arrays::asList)
        .toList();

为了成为“数组的数组”,它需要是一个二维数组:

String[][] arrays = new String[][] {new String[] {"add, hack"}, ...}

然后你可以将数组中的每个数组转换为列表中的一个项目

List<List<String>> list = new ArrayList<>();
for (String[] array : arrays) {
    list.add(Arrays.asList(array));
}

代码中源数组中的每个数组,如 new String[] {"add, hack"} 都被视为 Object - 这就是编译器所知道的全部内容,因为 array 已被声明为 Object[](即对象数组,而不是数组对象数组或字符串数​​组数组)。

Arrays.asList(array.toString()) - 创建一个包含 String 类型的单个元素的列表。当您在任何类型的数组上调用 toString() 时,您将获得一个字符串,其中包含数组的类型和 at-sign @ 之后的 hash-based 符号序列。为了获得数组内容的字符串表示,您需要使用 Arrays class.

的静态方法 toString()

这样你就可以解决转换 Object 类型数组的问题

public static void main(String[] args) {
    Object[][] array =  new Object[][]{
        new String[] {"add, hack"},
        new String[] {"add, hackerrank"},
        new String[] {"find, hac"},
        {"find, hak"} // you can omit new String[] when assigning array while at the same time with initialization
    };    

    List<List<String>> list = arraysToList(array, String.class);

    System.out.println(list);
}

用于转换的通用方法,需要一个 Class 对象作为参数:

public static <T> List<List<T>> arraysToList(Object[][] array, Class<T> clazz) {
    return Stream.of(array)
        .map(arr -> Stream.of(arr).map(clazz::cast).toList())
        .collect(Collectors.toList());
}

输出

[[add, hack], [add, hackerrank], [find, hac], [find, hak]]

你的问题不清楚你的目标。也许您想生成特定格式的文本。如果是这样,请向记录 class Query 添加一个方法,即 returns 一个 String 对象以您想要的格式。


如果您需要将包含 non-alphabetic 个符号的单个字符串拆分为单独的单词,您可以使用 split() 方法:

str.split("[^\p{Alpha}]+"); // returns an array of strings comprised of alphabetic symbols only

假设您想从 Object[] 数组开始的另一种解决方案 - 首先使用转换转换为 String[] 列表,然后将每个 String[] 映射到 List:

    List<String[]> arrList = new ArrayList<>();

    for (Object o : array)
        arrList.add((String[]) o);

    List<List<String>> strList = arrList.stream()
            .map(Arrays::asList)
            .collect(Collectors.toList());

使用对象,而不是数组列表

其他答案似乎对你的各种问题都是正确的。我将着眼于更大的图景……您的设计方法忽略了 Java 的最佳特征:object-oriented programming

您的查询件应打包为 class、record.

record Query ( String verb , String noun ) {}

显然您是从 comma-separated string as inputs. So add a static factory method 开始解析每个输入的。

record Query ( String verb , String noun ) {
    // Factory method to instantiate `Query` object by parsing input string containing a pair of comma-separated values.
    public static Query parse( final String input ) {
        String[] parts = input.split( ", " ) ;
        return new Query ( parts[0] , parts[1] ) ;
    }
}

跳过数组,使用 ListSet 以方便使用。

List< Query > queries = 
    List.of(
        Query.parse( "add, hack" ) ,  // Instantiates a `Query` object. 
        Query.parse( "add, hackerrank" ) , 
        Query.parse( "find, hac" ) ,
        Query.parse( "find, hak" )
    )
;

正在生成文本

举报内容。

System.out.println( "queries = " + queries );

queries = [Query[verb=add, noun=hack], Query[verb=add, noun=hackerrank], Query[verb=find, noun=hac], Query[verb=find, noun=hak]]

您的问题的最终目标不明确。如果您的目标是生成特定格式的文本,请向您的 class 添加一个方法。这里我们添加一个名为 report.

的方法
String report ( ) { return String.format( "{ %s, %s }" , this.verb , this.noun ); }

要使用 report 方法,请循环对象,为每个对象生成文本。

queries.forEach( query -> System.out.println( query.report() ) );
{ add, hack }
{ add, hackerrank }
{ find, hac }
{ find, hak }

警告:在实际工作中,我们会做更多的工作来验证和验证。例如,我们将验证输入数据以确保输入字符串为 non-null, non-blank,并且由两部分组成。我省略了这样的代码以保持演示简短和 on-point.