I am trying to search something into a map and I wanted to do that with streams but I could not figure out how to do. Could anyone help please?
The old fashioned code is like this:
String softwareIp = "1.1.1.1";
String softwareName = "Soft"
Map<String, Object> mymap; // {"1.1.1.1-12": Obj, "1.1.1.1-13":Obj, "1.1.1.2-3:Obj...etc}
Obj object = null;
for (Map.Entry entry : mymap) {
if (entry.getKey().toString().contains(softwareIP)) {
if (entry.getValue().getName().contains(softwareName)) {
object = entry.getValue();
}
}
}
The stream code I tried to write:
Obj object = mymap.entrySet().stream()
.filter(e -> (e.getKey().toString().contains(softwareIP) &&
e.getValue().contains(softwareName)))
.map(mymap::get)
.findFirst()
.orElse(null);
Where is the problem in the stream code? What should I change? I returns null.
Try this one:
Object object = mymap.entrySet().stream()
.filter(e -> e.getKey().contains(softwareIp)
&& ((REFERENCE_CLASS) e.getValue()).getName().contains(softwareName))
.findFirst()
.map(Map.Entry::getValue) //<--- if you want value
//.map(Map.Entry::getKey) //<--- if you want key
.orElse(null);
Your stream solution is correct but the comparison is wrong.
Wrong: e.getValue().contains(softwareName)
Correct: e.getValue().getName().contains(softwareName)
try this .map(n -> n.getValue())
String softwareIp = "1.1.1.1";
String softwareName = "Soft";
Map<String, String> mymap = new HashMap<>(); // {"1.1.1.1-12": Obj, "1.1.1.1-13":Obj, "1.1.1.2-3:Obj...etc}
mymap.put("1.1.1.1-12", "Soft");
String obj;
obj = mymap.entrySet().stream()
.filter(e -> (e.getKey().contains(softwareIp) &&
e.getValue().contains(softwareName)))
.map(n -> n.getValue())
.findFirst()
.orElse(null);
System.out.println(obj);
Related
I have: List<Map<String, String>> countries and I was able to get value which I am interested in by this:
String value = "";
for (int i = 0; i < countries.size(); i++) {
Map<String, String> map = countries.get(i);
if (map.containsValue(country)) {
value = map.get(COUNTRY_NAME);
}
}
return value;
so in general - if in map is country which I am interested in then I take value where key is COUNTRY_NAME.
How can I translate it to streams? I tried this way:
for (Map<String, String> m : countries) {
description = String.valueOf(m.entrySet()
.stream()
.filter(map -> map.getValue().equals(country))
.findFirst());
}
but first it doesn't work, second I still used for each loop.
You need to filter map if it's containsValue then transform your data using .map() then after .findFirst() use .orElse() to return default value if not found.
String value = countries.stream()
.filter(m -> m.containsValue(country))
.map(m -> m.get(COUNTRY_NAME))
.findFirst()
.orElse("");
I think you can try:
Stream.of(countries).reduce(Stream::concat)
.filter(map -> map.getValue().equals(country))
.findFirst();
That page seems to show things that can help you.
Check this:
Optional<Map<String, String>> countryOpt = countries
.stream()
.filter(c -> c.containsValue(COUNTRY_NAME))
.findAny();
if (countryOpt.isPresent()) {
value = countryOpt.get().get(COUNTRY_NAME);
}
Optional<String> countryOptional = countries.stream()
.filter(kvp -> kvp.containsKey(COUNTRY_NAME))
.map(kvp -> kvp.get(COUNTRY_NAME))
.findFirst();
I have the following Map structure
{empId=1234, empName=Mike, CDetails=[{"collegeName":"Peters Stanford","collegeLoc":"UK","collegeLoc":"UK"}]}
I need to read the value collegeLoc from the above Map
I tried this way , its working , but is there any better way
myMap.entrySet().stream().filter(map -> map.getKey().equals("CDetails")).forEach(e -> {
List<Object> objsList = (List<Object>) e.getValue();
for(int i=0;i<objsList.size();i++)
{
HashMap<String,String> ltr = (HashMap<String, String>) objsList.get(i);
System.out.println(ltr.get("collegeLoc"));
}
});
CDetails is a List, not a Map.
Try this:
empMap.entrySet().stream()
.map(map -> map.get("CDetails"))
.filter(Objects::nonNull)
.flatMap(List::stream)
.map(element -> ((Map)element).get("collegeLoc"))
.filter(Objects::nonNull)
.forEach(System.out::println);
Using Map of key to iterate and based on condition returning HashMap,need to collect return map below code.
trying to convert below java code in java 8
for (String key : sectionsJson.keySet()) {
Map<String, Object> section = (Map<String, Object>) sectionsJson.get(key);
if (index == (Integer) section.get(SECTION_FIELD_KEY_INDEX)) {
section.put(SECTION_FIELD_KEY_SECTION_KEY, key);
return section;
}
}
any suggestion.
It looks like you want to produce a Map having at most a single entry.
Map<String,Object> map =
sectionsJson.entrySet()
.stream()
.filter(e -> {
Map<String, Object> section = e.getValue ();
return index == (Integer) section.get(SECTION_FIELD_KEY_INDEX);
}
.map(e -> new SimpleEntry<> (SECTION_FIELD_KEY_SECTION_KEY, e.getKey ()))
.limit(1)
.collect(Collectors.toMap(Map.Entry::getKey,Map.Entry::getValue));
It looks like your original code is simpler.
Perhaps you can simply search for the desired key:
String value =
sectionsJson.entrySet()
.stream()
.filter(e -> {
Map<String, Object> section = e.getValue ();
return index == (Integer) section.get(SECTION_FIELD_KEY_INDEX);
}
.map(Map.Entry::getKey)
.findFirst()
.orElse(null);
since you are producing a Map having (at most) a single value and a constant key, so the value is the only data the Stream pipeline should be searching for.
As per your existing code. You are returning the map as soon as it finds any match. Same thing you can do using java 8 as well.
Optional<Integer> findAny = sectionsJson.keySet().stream().filter(key -> {
Map<String, Object> section = (Map<String, Object>)sectionsJson.get(key);
if (index == (Integer)section.get("SECTION_FIELD_KEY_INDEX")) {
section.put("SECTION_FIELD_KEY_SECTION_KEY", key);
return true;
}
return false;
}).findFirst();
if (findAny.isPresent()) {
System.out.println(sectionsJson.get(findAny.get()));
}
Depending on what you want to achieve following might be also possible solutions:
simplifying the loop
for (Map.Entry<String, Map<String, Object>> entry : sectionsJson.entrySet()) {
Map<String, Object> section = entry.getValue();
if (index == section.get(SECTION_FIELD_KEY_INDEX)) {
section.put(SECTION_FIELD_KEY_SECTION_KEY, entry.getKey());
return section;
}
}
// add the code for the case when no section was found
separate stream processing and mutating the element
// find the section
Optional<Map.Entry<String, Map<String, Object>>> first = sectionsJson.entrySet().stream()
.filter(e -> (Integer) e.getValue().get(SECTION_FIELD_KEY_INDEX) == index)
.findFirst();
// mutate the section
if (first.isPresent()) {
Map.Entry<String, Map<String, Object>> sectionJson = first.get();
sectionJson.getValue().put(SECTION_FIELD_KEY_SECTION_KEY, sectionJson.getKey());
return sectionJson.getValue();
}
// add the code for the case when no section was found
How do I write below code using Java8?
for (Entry<Integer, Map<String, Object>> entry : data.entrySet()) {
Map<String, Object> value = entry.getValue();
if (value.get(Constants.USER_TRAN_ID).equals(stsTxn.getSeedTrade().getTransactionId())) {
closedTaxLotByTxnId = value;
break;
}
}
I am clueless after this
data.values().stream().map(e -> e.get(Constants.USER_TRAN_ID)).filter(txnId -> txnId.equals(stsTxn.getSeedTrade().getTransactionId()));
You don't need map. Just use filter with your criteria, and findFirst as terminal operation:
Optional<Map<String, Object>>
value = data.values()
.stream()
.filter(m -> m.get(Constants.USER_TRAN_ID).equals(stsTxn.getSeedTrade().getTransactionId()))
.findFirst();
If you want a default value (such as null) when no match is found, use:
Map<String, Object> closedTaxLotByTxnId =
data.values()
.stream()
.filter(m -> m.get(Constants.USER_TRAN_ID).equals(stsTxn.getSeedTrade().getTransactionId()))
.findFirst()
.orElse(null);
I have a Map<String, List<Object>>.
How can I make it into a Stream of Entry<String, Object> so that I can construct a concatenated query String?
q1 a, b
q2 c, d
into
q1=a&q1=b&q2=c&q2=d
I'm, currently, doing this.
if (params != null && !params.isEmpty()) {
final boolean[] flag = new boolean[1];
params.forEach((n, vs) -> {
vs.forEach(v -> {
builder.append(flag[0] ? '&' : '?')
.append(n)
.append('=')
.append(v);
if (!flag[0]) {
flag[0] = true;
}
});
});
}
Well, you don't have to produce a Entry<String, Object>. You can use flatMap to obtain the key=value Strings and directly construct the query String using Collectors.joining:
String query =
map.entrySet()
.stream()
.flatMap(e -> e.getValue().stream().map(v -> e.getKey() + '=' + v))
.collect(Collectors.joining("&"));
Input :
{q1=[a, b], q2=[c, d]}
Output :
q1=a&q1=b&q2=c&q2=d
If you have Guava, you might want to consider using a ListMultimap<String, Object> instead of Map<String, List<Object>>, and create your string like so:
String query = Joiner.on("&").withKeyValueSeparator("=").join(map.entries());