java—如何展平同时包含字符串和字符串列表的列表?

gg58donl  于 2021-07-08  发布在  Java
关注(0)|答案(4)|浏览(495)

如何最好地压平 ArrayList<Object> 其中包含了 ArrayList<String> 以及 String 将对象放入平面 ArrayList<String> ?
例子
输入: [item1, item2, item3, [item4a, item4b, item4c]] 预期产量: [item1, item2, item3, item4a, item4b, item4c] 创建虚拟示例的代码:

ArrayList<Object> objectList = new ArrayList<Object>();
objectList.add("item1");
objectList.add("item2");
objectList.add("item3");

ArrayList<String> subList = new ArrayList<String>();
subList.add("item4a");
subList.add("item4b");
subList.add("item4c");

objectList.add(subList);

(非)工作解决方案

private ArrayList<String> flattenList(ArrayList<Object> objectList) {
    ArrayList<String> flatLst = new ArrayList<String>();

    for (Object item :  objectList) {
        if (item.getClass() == ArrayList.class) {
            System.out.println(item);
            for (Object s : item) {
                flatLst.add(String.valueOf(s));
            }
        } else if (item.getClass() == String.class) {
            flatLst.add(String.valueOf(item));
        }
    }
    return flatLst;
}

这将产生以下错误。

|               for (Object s : item) {
for-each not applicable to expression type
  required: array or java.lang.Iterable
  found:    java.lang.Object

问题:如何解决这个问题?或者更好,有什么更干净的方法来解决这个问题?

u0njafvf

u0njafvf1#

for each循环需要数组或 Iterable 作为它们的右操作数。类型 itemObject ,所以你需要先投。

if (item.getClass() == ArrayList.class) {
        ArrayList list = (ArrayList) item;
        for (Object s : list) {
            flatLst.add(String.valueOf(s));
        }
    }
3ks5zfa0

3ks5zfa02#

使用流api

ArrayList<Object> objectList = new ArrayList<Object>();
objectList.add("item1");
objectList.add("item2");
objectList.add("item3");

ArrayList<String> subList = new ArrayList<String>();
subList.add("item4a");
subList.add("item4b");
subList.add("item4c");

objectList.add(subList);
List<Object> flat = objectList.stream()
                              .map(obj -> (obj instanceof List) ? (List<Object>) obj : List.of(obj))
                              .flatMap(list -> list.stream())
                              .collect(Collectors.toList());
System.out.println(flat);

上面的代码打印。。。

[item1, item2, item3, item4a, item4b, item4c]

编辑

按要求。 List<String> 而不是 List<Object> ```
List flat = objectList.stream()
.map(obj -> (obj instanceof List) ? (List) obj : List.of(obj))
.flatMap(list -> list.stream())
.map(obj -> String.valueOf(obj))
.collect(Collectors.toList());

raogr8fs

raogr8fs3#

您必须通过如下方式强制转换项来帮助编译器:

for (Object s : (List) item) {

或者,如果您想要一个优雅的解决方案,您可以使用如下流:

private ArrayList<String> flattenList(ArrayList<Object> objectList) {
    return objectList.stream()
            .flatMap(this::extract)
            .collect(Collectors.toCollection(ArrayList::new));

}

private Stream<String> extract(Object item) {
    if (item.getClass() == ArrayList.class) {
        return ((List<String>) item).stream();
    } else if (item.getClass() == String.class) {
        return Stream.of((String) item);
    }
    return Stream.empty();
}
lg40wkob

lg40wkob4#

如果必须使用loop,那么这里有另一种做同样事情的方法。如果你能使用java8比ycf\u l的解决方案更好。

public static ArrayList<String> flattenList(ArrayList<Object> objectList) {
        ArrayList<String> flatLst = new ArrayList<String>();

        for (Object item :  objectList) {
            if (item instanceof List) {
                System.out.println(item);
                for (Object s : (List)item) {
                    flatLst.add(String.valueOf(s));
                }
            } else if (item instanceof String ) {
                flatLst.add(String.valueOf(item));
            }
        }
        return flatLst;
    }

相关问题