Java 从具有多个条件的映射中筛选出结果

Java 从具有多个条件的映射中筛选出结果,java,collections,java-8,Java,Collections,Java 8,我有一张地图,上面有empid和name的列表。我只想选择emp name的id大于7且名称以N开头的人员。 必须设置结果 我尝试使用map.entryset(),但无法思考如何在map内部进行过滤 我们必须使用if-else吗? 如果找到多个元素,我们将如何返回set?Map nameMap=new HashMap()//带有empid和emp名称的虚拟映射 Map<Integer, String> nameMap = new HashMap<>(); //A dumm

我有一张地图,上面有
empid
name
的列表。我只想选择
emp name
id
大于7且名称以N开头的人员。 必须设置结果

我尝试使用
map.entryset()
,但无法思考如何在map内部进行过滤

我们必须使用if-else吗? 如果找到多个元素,我们将如何返回set?

Map nameMap=new HashMap()//带有empid和emp名称的虚拟映射
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);
}
公共静态void main(字符串[]args){ 姓名地图。放置(1,“John”); 名称映射。put(2,“Doe”); 名称地图。放置(37,“霓虹灯”); 姓名地图(14,“Shaun”); 姓名地图(35,“Jason”); nameMap.put(0,“NEO”); Set empSet=nameMap.entrySet() .stream() .filter(x->x.getKey()>7和&x.getValue().startsWith(“N”)) .map(x->x.getValue()) .collect(收集器.toSet()); empSet.forEach(System.out::println); }
实际的实现和名称空间会有所不同,但基本的 行动将保持不变


应该是这样的,

Set<String> selectedEmps = empIdToName.entrySet().stream()
    .filter(e -> e.getKey() > 7)
    .filter(e -> e.getValue().startsWith("N"))
    .map(Map.Entry::getValue)
    .collect(Collectors.toSet());
Set selectedEmps=empIdToName.entrySet().stream()
.filter(e->e.getKey()>7)
.filter(e->e.getValue().startsWith(“N”))
.map(map.Entry::getValue)
.collect(收集器.toSet());

如果我理解正确,这里有一个解决方案: 假设我们有以下数据:

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)));

通过一个简单的for循环可以非常轻松地完成:

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);
        }
    }
}
Map=。。。
Set result=new HashSet();
对于(Map.Entry:Map.entrySet()){
if(entry.getKey()>7){
字符串名称=entry.getValue();
if(name.charAt(0)='N'){
结果。添加(名称);
}
}
}

注意:如果名称可以为空(
length()==0
),则
name.charAt(0)
方法将不起作用,因为您将得到一个
StringIndexOutOfBoundsException

显示您迄今为止尝试过的内容。如果您想使用if/else,则需要在对映射值进行迭代的for循环中执行此操作,将符合条件的存储在结果集或映射中。一个更现代的替代方案是使用流,但如果您不熟悉它们,我认为您不应该在找到一个有效的解决方案之前打扰他们。我们不能使用for loop吗??为什么每个人都在使用stream?@mukka因为它的标签也带有java8。你也能定义你的地图吗?@mukka请显示mapi think op要求结果在集合中的声明:Puse
filter(e->e.getValue().stream().anyMatch(id->id)如果我们使用
.filter(e->e.getKey()>7.filter)是否有任何缺点(e->e.getValue().startsWith(“N”))
&&
运算符在同一个筛选器中??有任何性能问题吗?我认为这两种方法或多或少是相同的。但我不知道运行时如何对其进行优化。即使StackOverflow也表明命名样式不好,例如,查看变量名并将其与类名
Map
Integer
等进行比较。使用变量名小写。@nullpointer,好的,我编辑了它,但所有缩进现在都是hapazard,这里有没有让代码对齐的快捷方式???@CommonMan我也编辑了格式和原始类型注释的答案。你可能在我上次编辑时就知道了。@nullpointer,我仍然在通过查看你的所有答案来学习,但是当你把你的代码从IDE复制粘贴到这里时,如何纠正对齐方式呢?就像你在这里编辑过一样,你的对齐方式被破坏了,你的代码看起来又大又丑??你是把代码复制回IDE,然后对齐,然后再粘贴到这里还是什么?他引用了他的句子:
我有一个地图,上面有empid和name的列表
。我也知道输入应该是这种形式的
Map
但我不确定是否诚实,OP至少应该定义Map。经典方法。
Noo [8, 8, 9]
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);
        }
    }
}