如何展平包含字符串和字符串列表的列表?
How to flatten a list containing both strings and lists-of-strings?
如何最好地将包含 ArrayList<String>
和 String
对象的 ArrayList<Object>
扁平化为扁平的 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
问题:如何解决这个问题?或者更好的是,解决此问题的更简洁方法是什么?
您必须像这样转换项目来帮助编译器:
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();
}
For-each 循环需要数组或 Iterable
的实例作为其右侧操作数。 item
的类型是Object
,所以需要先投
if (item.getClass() == ArrayList.class) {
ArrayList list = (ArrayList) item;
for (Object s : list) {
flatLst.add(String.valueOf(s));
}
}
使用 stream 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<String> flat = objectList.stream()
.map(obj -> (obj instanceof List) ? (List<Object>) obj : List.of(obj))
.flatMap(list -> list.stream())
.map(obj -> String.valueOf(obj))
.collect(Collectors.toList());
如果你必须使用循环来做同样的事情,这里有另一种方法。如果你可以使用 java8 比 的解决方案更好。
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;
}
如何最好地将包含 ArrayList<String>
和 String
对象的 ArrayList<Object>
扁平化为扁平的 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
问题:如何解决这个问题?或者更好的是,解决此问题的更简洁方法是什么?
您必须像这样转换项目来帮助编译器:
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();
}
For-each 循环需要数组或 Iterable
的实例作为其右侧操作数。 item
的类型是Object
,所以需要先投
if (item.getClass() == ArrayList.class) {
ArrayList list = (ArrayList) item;
for (Object s : list) {
flatLst.add(String.valueOf(s));
}
}
使用 stream 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<String> flat = objectList.stream()
.map(obj -> (obj instanceof List) ? (List<Object>) obj : List.of(obj))
.flatMap(list -> list.stream())
.map(obj -> String.valueOf(obj))
.collect(Collectors.toList());
如果你必须使用循环来做同样的事情,这里有另一种方法。如果你可以使用 java8 比
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;
}