Reputation: 229
I have the ArrayList:
List<String> wordsList = new ArrayList<>();
// [eu, quero, voltar, para, praia, e, comer, queijo]
And the HashMap:
Map<String, String> wordsMap = new HashMap<>();
//{v.=voltar, c.=comer, q.=queijo., p.=praia}
I am trying to do: If the list element is equal to map value, then replace the list element by the map key. In this example, the result would be:
// [eu, quero, v., para, p., e, c., q.]
Something that I tried was
for (String word : wordsList) {
for (Map.Entry<String, String> entry : wordsMap.entrySet()) {
String key = entry.getKey();
String value = entry.getValue();
if (word.equals(value)) {
newWordsList.add(key);
} else {
newWordsList.add(word);
}
}
}
Result: [eu, eu, eu, eu, quero, quero, quero, quero, v., voltar, voltar, voltar, para, para, para, para, praia, praia, praia, p., e, e, e, e, comer, c., comer, comer, queijo, queijo, q., queijo]
Any help?? thanks!
Upvotes: 0
Views: 2668
Reputation: 79015
You can simply iterate the wordsMap.entrySet()
, find the index of the entry#value
in wordsList
, and update wordsList
at the index with the entry#key
.
Demo:
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class Main {
public static void main(String[] args) {
List<String> wordsList = new ArrayList<>(
List.of("eu", "quero", "voltar", "para", "praia", "e", "comer", "queijo."));
Map<String, String> wordsMap = Map.of("v.", "voltar", "c.", "comer", "q.", "queijo.", "p.", "praia");
for (Map.Entry<String, String> entry : wordsMap.entrySet()) {
int index = wordsList.indexOf(entry.getValue());
if (index != -1) {
wordsList.set(index, entry.getKey());
}
}
System.out.println(wordsList);
}
}
Output:
[eu, quero, v., para, p., e, c., q.]
Note: List#indexOf
returns the index of the first occurrence of the specified element in this list, or -1
if this list does not contain the element. Therefore the logic in the solution given above checks for -1
and also, only the first occurrence of the matching value will be replaced. If your list has duplicate elements and you want all occurrences of the matching value to be replaced, you need to find all indices of the matching value and replace them as shown below:
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
List<String> wordsList = new ArrayList<>(List.of("eu", "quero", "queijo.", "voltar", "queijo.", "para", "praia",
"e", "queijo.", "comer", "queijo."));
Map<String, String> wordsMap = Map.of("v.", "voltar", "c.", "comer", "q.", "queijo.", "p.", "praia");
for (Map.Entry<String, String> entry : wordsMap.entrySet()) {
List<Integer> allIndices = allIndicesOf(wordsList, entry.getValue());
for (int index : allIndices) {
wordsList.set(index, entry.getKey());
}
}
System.out.println(wordsList);
}
static List<Integer> allIndicesOf(List<String> list, String str) {
return IntStream.range(0, list.size())
.boxed()
.filter(i -> list.get(i).equals(str))
.collect(Collectors.toList());
}
}
Output:
[eu, quero, q., v., q., para, p., e, q., c., q.]
Upvotes: 1
Reputation: 1872
Given the list and the map:
List<String> wordsList = Arrays.asList("eu", "quero", "voltar", "para", "praia", "e", "comer", "queijo");
Map<String, String> wordsMap = Map.of("v.", "voltar", "c.", "comer", "q.", "queijo", "p.", "praia");
Then the code below returns your results (without any external dependency):
// If the list element is equal to map value, then replace the list element
// by the map key.In this example, the result would be:
wordsMap.values().stream()
// If the list contains the map value
.filter(wordsList::contains)
.forEach(value -> {
// Find the corresponding map key
String mapKey = wordsMap.entrySet()
.stream()
.filter(entry -> Objects.equals(entry.getValue(), value))
.map(Map.Entry::getKey) // It could find several keys if you have the same value for different keys
.findFirst()
.orElseThrow(); // It should never happen as we are looping in the map values
// Find the index and update the list with the map key
int index = wordsList.indexOf(value);
wordsList.set(index, mapKey);
});
System.out.println(wordsList);
// [eu, quero, v., para, p., e, c., q.]
Upvotes: 0
Reputation: 1914
First step for me would be to create a new map that uses the value as key and the key as value. That is much easier than looping through the old map and checking for values.
Map<String, String> invertedWordsMap = wordsMap.entrySet().stream().collect(Collecotrs.toMap(Map.Entry::getValue), Map.Entry::getKey));
//{voltar=v., comer=c., queijo=q.., praia=p.}
And then I just have to check if the key exists in the map
for (int i = 0; i < wordsList.size(); i++) {
String word = invertedWordsMap.get(wordsList.get(i));
if (word != null) {
wordsList.set(i, word);
}
}
And here is the obligatory fancy stream answer. Just keep in mind that the old list is replaced and not changed if you use the stream solution.
wordsList = wordsList.stream().map(word -> invertedWordsMap.getOrDefault(word, word)).collect(Collectors.toList());
Upvotes: 4
Reputation: 375
I'd use a google HashBiMap<String, String> because it can provide an inverse view of the same map, i.e. In a Map<K,V>
you can do both get(K) returns V
and get(V) returns K
// Form the words list
List<String> wordsList = new ArrayList<String>();
wordsList.add("eu");
wordsList.add("quero");
// etc adding all of the terms you mentioned
// Form the keyset
HashBiMap<String, String> wordsMap = HashBiMap.create();
wordsMap.put("v", "voltar");
wordsMap.put("c", "comer");
// etc adding all the terms you mentioned
List<String> wordsListOut = new ArrayList<String>();
// Iterating through the wordsList
for (int i = 0; i < wordsList.size(); i++) {
// Get the current element
String element = wordsList.get(i);
// Does it have an inverse pair?
String result = wordsMap.inverse().get(element);
// If it has an inverse pair, add the inverse key. Otherwise, add the element raw.
wordsListOut.add(result == null ? element : result);
}
// Outputs: [eu, quero, v, para, p, e, c, q]
System.out.println(wordsListOut);
The dependency for HashBiMap is Google Guava:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1-jre</version>
</dependency>
Upvotes: 0