List<String>转换为ArrayList<String>的问题

109

我有一个以下的方法...它实际上接受句子列表并将每个句子分割成单词。这是它:

public List<String> getWords(List<String> strSentences){
allWords = new ArrayList<String>();
    Iterator<String> itrTemp = strSentences.iterator();
    while(itrTemp.hasNext()){
        String strTemp = itrTemp.next();
        allWords = Arrays.asList(strTemp.toLowerCase().split("\\s+"));          
    }
    return allWords;
}

我必须按照以下格式将这个列表传递到哈希映射中

HashMap<String, ArrayList<String>>

所以这个方法返回List,但我需要一个ArrayList?如果我试图进行强制类型转换,它不起作用...有什么建议吗?

另外,如果我将HashMap中的ArrayList更改为List,我会得到

java.lang.UnsupportedOperationException

因为我的代码中有这一行

sentenceList.add(((Element)sentenceNodeList.item(sentenceIndex)).getTextContent());

有更好的建议吗?

9个回答

211

当列表的实际实例是ArrayList时,Cast方法可以正常工作。如果它是一个Vector(另一个List的扩展),那么就会抛出一个ClassCastException异常。

更改HashMap的定义后导致元素在后续处理时出错,因为该过程期望只在ArrayList中定义的方法。异常告诉您它没有找到它正在寻找的方法。

使用旧列表的内容创建一个新的ArrayList

new ArrayList<String>(myList);

55
首先,为什么这个地图是一个 HashMap<String, ArrayList<String>> 而不是一个 HashMap<String, List<String>>?是否有一些原因要求值必须是接口 List 的特定实现(在这种情况下是 ArrayList)? Arrays.asList 不返回 java.util.ArrayList ,因此您无法将 Arrays.asList 的返回值分配给类型为 ArrayList 的变量。
而应该使用:
allWords = Arrays.asList(strTemp.toLowerCase().split("\\s+"));

试试这个:

allWords.addAll(Arrays.asList(strTemp.toLowerCase().split("\\s+")));

3
UnsupportedOperationException的出现是因为Arrays.asList方法返回一个由数组支持的固定大小的列表 - 无法修改。@Jesper在这里提出的解决方案将避免这种情况。 - Duncan Jones

46

请查看ArrayList#addAll(Collection)

将指定集合中的所有元素按照迭代器返回顺序添加到此列表的末尾。如果在操作进行时修改了指定的集合,则此操作的行为是未定义的。(这意味着,如果指定的集合是此列表并且此列表非空,则此调用的行为是未定义的)。

因此,您可以使用

ArrayList<String> listOfStrings = new ArrayList<>(list.size());
listOfStrings.addAll(list);

20
在 Kotlin 中,可以通过将 List 作为构造函数参数传递来将其转换为 ArrayList。
ArrayList(list)

5

Arrays.asList并不返回 java.util.ArrayList 的实例,而是返回 java.util.Arrays.ArrayList 的实例。

如果你想访问 ArrayList 特定的信息,你需要将其转换为 ArrayList。

allWords.addAll(Arrays.asList(strTemp.toLowerCase().split("\\s+")));

0

ArrayList<String> listOfStrings = new ArrayList<>(list.length); listOfStrings.addAll(Arrays.asList(list));

如果是对象列表,您可以使用以下方式将 Model[] 列表转换为 ArrayList。


0
这可能有点晚了,但我想以简单的方式回答“将List转换为ArrayList”的问题。
简单方法
public static <T> ArrayList<T> listToArrayList(List<T> list) {
    return list != null ? new ArrayList<>(list) : null;
}

传统方式

public static  <T> ArrayList<T>  listToArrayList(List<T> list) {
    ArrayList<T> arrayList = new ArrayList<>();
    if (list != null) {
        for (int i = 0; i < list.size(); i++) {
            arrayList.add(list.get(i));
            i++;
        }
        // or simply
        // arrayList.addAll(list);
    }
    return  arrayList;
}

使用方法

listToArrayList(yourList);

0

经过尝试和测试的方法。

public static ArrayList<String> listToArrayList(List<Object> myList) {
        ArrayList<String> arl = new ArrayList<String>();
        for (Object object : myList) {
            arl.add((String) object);
        }
        return arl;

    }

0

随着Java流API的出现(2014年3月),以下方法现在可能被认为是首选:

    public List<String> getWordsFunctionally(List<String> sentences) { 
        List<String> list = sentences.stream()
            .map(s -> List.of(s.toLowerCase().replaceAll("\\p{Punct}", "").split("\\s+")))
            .flatMap(List::stream)
//          .distinct() // if you don't want duplicates
            .collect(Collectors.toList());
        
        return list;
    }

请注意,原始代码存在一个错误:在每次迭代中,allWords 中的值都会被当前从句子中拆分出来的数组替换。
allWords = Arrays.asList(strTemp.toLowerCase().split("\\s+")); 

这应该是

allWords.addAll(Arrays.asList(strTemp.toLowerCase().split("\\s+"))); 

此外,它不会去除标点符号。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接