Пожалуйста, ознакомьтесь со следующим кодом
private StringBuffer populateStringWithUnmatchingWords(ArrayList<String>unmatchingWordsHolder)
{
StringBuffer unMatchingWordsStr = new StringBuffer("");
for(int u=0;u<unmatchingWordsHolder.size();u++)
{
Iterator iterInWordMap = wordMap.entrySet().iterator();
while(iterInWordMap.hasNext())
{
Map.Entry mEntry = (Map.Entry)iterInWordMap.next();
if(mEntry.getValue().equals(unmatchingWordsHolder.get(u)))
{
//out.println(matchingWords.get(m)+" : "+true);
unMatchingWordsStr.append(mEntry.getKey());
unMatchingWordsStr.append(",");
}
}
}
return unMatchingWordsStr;
}
Это for loop
занимает 8387ms для завершения. unmatchingWordsHolder
тоже очень большой. wordMap
- это HashMap
и содержит около 5000 элементов.
Этот цикл будет искать, доступны ли элементы в unmatchingWordsHolder
в wordMap
. Если они доступны, они будут загружены в unMatchingWordsStr
.
Есть ли способ ускорить эту задачу?
Помогает ли вообще использовать Collection.contains()
? Это было бы гораздо читабельнее, если не больше, на мой взгляд. Это зависит от относительных размеров List
и Map
хотя, поскольку самый простой способ сделать это, это будет что-то вроде этого, хотя, поскольку вы повторяете Map
и просматриваете List
, если Map
намного больше чем в List
это не будет идеальным:
private StringBuffer populateStringWithUnmatchingWords(ArrayList<String>unmatchingWordsHolder) {
StringBuffer unMatchingWordsStr = new StringBuffer();
for (Entry<String, String> entry : wordMap.entrySet()) {
if(unmatchingWordsHolder.contains(entry.getValue())) {
//out.println(matchingWords.get(m)+" : "+true);
unMatchingWordsStr.append(entry.getKey());
unMatchingWordsStr.append(",");
}
}
return unMatchingWordsStr;
}
Как уже упоминалось в другом месте, если вам не нужна безопасность потоков, StringBuilder
обычно предпочитает StringBuffer
, но я не хочу связываться с вашими сигнатурами методов.
wordMap.contains(word)
где word
- это слово из unmatchingWordsHolder
списка unmatchingWordsHolder
. Это было бы намного быстрее.
for-each not applicable to expression type required: array or java.lang.Iterable found: HashMap
Вы повторяете каждый элемент Map
. Лучший способ сделать это - использовать HashMap
и использовать contains()
чтобы определить, существует ли он в HashMap
.
Не уверен, правильно ли я получил ваш запрос проблемы, но если вы хотите вернуть строку, разделенную запятыми, всеми словами, которые находятся в другом наборе слов, вот как вы это сделаете в Java 8:
private String populateContainedWords(List<String> words, Set<String> wordSet)
{
StringJoiner joiner = new StringJoiner(", ");
words.stream().filter(wordSet::contains).forEach(joiner::add);
return joiner.toString();
}
И если вы хотите иметь только отдельные слова в этой разделимой запятой строке, используйте следующий подход:
private String populateDistinctlyContainedWords(List<String> words, Set<String> wordSet)
{
StringJoiner joiner = new StringJoiner(", ");
words.stream().distinct().filter(wordSet::contains).forEach(joiner::add);
return joiner.toString();
}
И если вы хотите, чтобы строка слов, разделенных запятыми, из списка words
, которые НЕ содержатся в wordSet
вот как это сделать:
private String populateDisjointWords(List<String> words, Set<String> wordSet)
{
StringJoiner joiner = new StringJoiner(", ");
words.stream().filter(n -> !wordSet.contains(n)).forEach(joiner::add);
return joiner.toString();
}