-3

I have a Map with list of empid and name. I want to select only emp name of people whose id is greater than 7 and name starts with N. The result must be SET.

I tried using map.entryset() but cannot think how to filter inside map.

Do we have to use if else? How we will return to set if multiple elements are found?

Molly
  • 1,887
  • 3
  • 17
  • 34
  • 5
    Show us what you have tried so far? – Ravindra Ranwala Feb 01 '19 at 09:38
  • If you want to use if/else, you will need to do it inside a for loop that iterates over the values of the map, storing those which match your criteria in a result set or map. A more modern alternative would be to use a stream, but if you're not familiar with them I think you shouldn't bother before you've got a working solution. – Aaron Feb 01 '19 at 09:42
  • Cant we use for loop?? Why everyone is using stream? –  Feb 01 '19 at 09:47
  • 2
    @mukka because its tag with java8 too .Also can you define your map ? – soorapadman Feb 01 '19 at 09:48
  • @mukka please show the declaration of the map – Lino Feb 01 '19 at 09:59

4 Answers4

3

It should be something like this,

Set<String> selectedEmps = empIdToName.entrySet().stream()
    .filter(e -> e.getKey() > 7)
    .filter(e -> e.getValue().startsWith("N"))
    .map(Map.Entry::getValue)
    .collect(Collectors.toSet());
Ravindra Ranwala
  • 20,744
  • 6
  • 45
  • 63
  • is there any disadvantage if we use `.filter(e -> e.getKey() > 7) .filter(e -> e.getValue().startsWith("N"))` in same filter with `&&` operator?? any performance issue? – Vishwa Ratna Feb 01 '19 at 09:55
  • 1
    I think both approaches are more or less the same. I have no idea on how the runtime optimizes it though. – Ravindra Ranwala Feb 01 '19 at 10:24
1

If I understand you correctly, here's a solution: Suppose we have this data:

Map<String, List<Integer>> map = new HashMap<>();

map.put("Noo", new ArrayList<>(Arrays.asList(8,8,9)));
map.put("No", new ArrayList<>(Arrays.asList(1,8,9)));
map.put("Aoo", new ArrayList<>(Arrays.asList(8,8,9)));

We can filter the data in this way:

map.entrySet().
            stream()
            .filter(e -> e.getKey().startsWith("N"))
            .filter(e -> e.getValue().stream().filter(id -> id <= 7).findAny().orElse(0) == 0)
            .map(Map.Entry::getKey)
            .collect(Collectors.toSet());

The first filter excludes the Names that does not start with "N", the second filter goes through the remaining entries and check if all their ids are greater than 7. In the foreach I just print the data, but you can change the logic to your needs

The result should the this:

Noo [8, 8, 9]
Schidu Luca
  • 3,897
  • 1
  • 12
  • 27
1

Can be done very easily with a simple for-loop:

Map<Integer, String> map = ...
Set<String> result = new HashSet<>();
for(Map.Entry<Integer, String> entry : map.entrySet()){
    if(entry.getKey() > 7){
        String name = entry.getValue();
        if(name.charAt(0) == 'N'){
            result.add(name);
        }
    }
}

Note: if the names can be empty (length() == 0) then the name.charAt(0) approach will not work as you'll get a StringIndexOutOfBoundsException

Lino
  • 19,604
  • 6
  • 47
  • 65
0
Map<Integer, String> nameMap = new HashMap<>(); //A dummy map with empid and name of emp
public static void main(String[] args) {
    nameMap.put(1,"John");
    nameMap.put(2,"Doe");
    nameMap.put(37,"Neon");
    nameMap.put(14,"Shaun");
    nameMap.put(35,"Jason");
    nameMap.put(0,"NEO");
    Set<String> empSet = nameMap.entrySet()
                        .stream()
                        .filter(x->x.getKey()>7 && x.getValue().startsWith("N"))
                        .map(x->x.getValue())
                        .collect(Collectors.toSet());
    empSet.forEach(System.out::println);
}

The actual implementation and namespaces will vary but the basic operations will remain same.

Naman
  • 27,789
  • 26
  • 218
  • 353
Vishwa Ratna
  • 5,567
  • 5
  • 33
  • 55
  • 1
    even StackOverflow indicates poor naming styles, for e.g. look at your variable name and compare it with the class name `Map`, `Integer` etc. Use lower case in variable names. – Naman Feb 01 '19 at 09:55
  • @nullpointer , ok man, i edited it, but all indent is now hapazard, any shortcut to make code align now here?? – Vishwa Ratna Feb 01 '19 at 09:58
  • [What is a raw type and why shouldn't we use it?](https://stackoverflow.com/questions/2770321/what-is-a-raw-type-and-why-shouldnt-we-use-it) – Lino Feb 01 '19 at 10:05
  • 1
    @CommonMan I've edited the answer for the formatting and raw type comment as well. You can possibly figure that one out in the last edit made by me. – Naman Feb 01 '19 at 10:06
  • @nullpointer , i am still learning by seeing your all answers, but how do correct alignment when you copy paste your code from IDE to here , think like you have edited here and now your alignment is destroyed and your code looks really big and ugly?? Do you copy back the code to IDE and then align it and again paste it here or what?? – Vishwa Ratna Feb 01 '19 at 10:14
  • Thankks @Lino as always :) – Vishwa Ratna Feb 01 '19 at 10:14