Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用streams java8基于条件修改HashMap_Java_Java 8_Hashmap_Java Stream - Fatal编程技术网

使用streams java8基于条件修改HashMap

使用streams java8基于条件修改HashMap,java,java-8,hashmap,java-stream,Java,Java 8,Hashmap,Java Stream,我想通过对映射键应用一些操作,从现有的HashMap创建一个HashMap。 假设我有一个字符串-> String sampleString= "SOSSQRSOP";` 然后通过从如下字符串中仅提取3个字符(将0作为值)创建了一个hashmap: Map messages=newhashmap(); 消息。放置(“SOS”,0); messages.put(“SQR”,0); 消息。放置(“SOP”,0); 实际任务是从给定字符串“SOS”中找出地图中每个键的不同字符的总编号,并将编号分

我想通过对映射键应用一些操作,从现有的
HashMap
创建一个
HashMap
。 假设我有一个字符串->

String sampleString= "SOSSQRSOP";` 
然后通过从如下字符串中仅提取3个字符(将0作为值)创建了一个hashmap:

Map messages=newhashmap();
消息。放置(“SOS”,0);
messages.put(“SQR”,0);
消息。放置(“SOP”,0);
实际任务是从给定字符串“SOS”中找出地图中每个键的不同字符的总编号,并将编号分配给每个键的值。 如下所示(最终结果):

Map messages=newhashmap();
消息。放置(“SOS”,0);
信息。放置(“SQR”,2);
信息。放入(“SOP”,1);
所以我使用下面给出的流在java8中编写代码:

    Map<String,Integer>  result= messages
            .entrySet().stream()
            .collect(Collectors.toMap(e-> e.getKey(),
                    e-> e.getKey().stream()
                         .forEach(x-> {
                                if(!"SOS".equals(x)){
                                    char[] characters= {'S','O','S'};
                                    char[] message= x.toCharArray();
                                    for(int i=0; i< characters.length;i++){
                                        int index=0;
                                        if(characters[i] != message[i]){
                                            messages.put(e.getKey(),++index);
                                        }
                                    }
                                }
                            });
                    ));
Map结果=消息
.entrySet().stream()
.collect(Collectors.toMap(e->e.getKey(),
e->e.getKey().stream()
.forEach(x->{
如果(!“SOS”。等于(x)){
char[]字符={S','O','S};
char[]message=x.toCharArray();
for(int i=0;i
我得到编译错误。有人能帮我用流写代码吗


编辑:还请描述其他实现此目的的方法。顺便说一句,在我的例子中,需要从给定字符串创建第一个hashmap。

您不能在值映射器中使用
forEach
,因为它不返回值

String x = "SOS";
Map<String,Integer> result = messages
        .entrySet().stream()
        .collect(Collectors.toMap(e-> e.getKey(),
                                  e-> {
                                          int count = 0;
                                          for (int i = 0; i < characters.length; i++){
                                              if (e.getKey().charAt(i) != x.charAt(i)) {
                                                  count++;
                                              }
                                          }
                                          return count;
                                      }));
String x=“SOS”;
映射结果=消息
.entrySet().stream()
.collect(Collectors.toMap(e->e.getKey(),
e->{
整数计数=0;
for(int i=0;i
在IMO中,您最好不要使用
s,而是
replaceAll

Map<String, Integer> messages = new HashMap<>();
// sample entries
messages.put("SOS", 0);
messages.put("SQR", 0);
messages.put("SOP", 0);

messages.replaceAll((k, v) -> {
    // calculate new value for each entry
    int diff = 0;
    for (int i = 0; i < "SOS".length(); i++) {
        if ("SOS".charAt(i) != k.charAt(i)) {
            diff++;
        }
    }
    return diff;
});
System.out.println(messages);
messages.replaceAll(
        (s, unused) -> (int) IntStream.range(0, 3)
                .filter(i -> "SOS".charAt(i) != s.charAt(i))
                .count()
);
Map messages=newhashmap();
//样本条目
消息。放置(“SOS”,0);
messages.put(“SQR”,0);
消息。放置(“SOP”,0);
messages.replaceAll((k,v)->{
//为每个条目计算新值
int-diff=0;
对于(int i=0;i<“SOS.length();i++){
如果(“SOS.charAt(i)!=k.charAt(i)){
diff++;
}
}
返回差;
});
System.out.println(消息);
输出

{SQR=2,SOP=1,SOS=0}


无需预先制作
HashMap
。流收集器
toMap
将为您提供:

import static java.util.stream.Collectors.toMap;

Map<String, Integer> result = Stream.of("SOS", "SQR", "SOP")
        .collect(toMap(
                s -> s,
                s -> (int) IntStream.range(0, 3)
                        .filter(i -> "SOS".charAt(i) != s.charAt(i))  // assume all words are 3-letters
                        .count()
         ));
如果您的任务是拆分源消息并将每个三元组与前3个字符进行比较,则可以将其组合到一个流表达式中:

String message = "SOSSQRSOP";
int n = 3;

assert message.length() % n == 0;

Map<String, Integer> messages = IntStream.range(0, message.length() / n)
        .map(i -> i * n) // starting points of the n-grams
        .mapToObj(idx -> message.substring(idx, idx + n))
        .collect(toMap(
                group -> group,
                group -> (int) IntStream.range(0, n)
                        .filter(i -> message.charAt(i) != group.charAt(i))
                        .count()
        ));
String message=“SOSSQRSOP”;
int n=3;
断言消息长度()%n==0;
Map messages=IntStream.range(0,message.length()/n)
.map(i->i*n)//n-grams的起点
.mapToObj(idx->message.substring(idx,idx+n))
.收集(
组->组,
组->(int)IntStream.range(0,n)
.filter(i->message.charAt(i)!=group.charAt(i))
.count()
));

您正在执行以下操作:
e.getKey().stream()
,这意味着您正在尝试对单个值进行流式处理,因为您的键是字符串,而这是不可能的

您可以执行
e.getKey().chars().forEach(…)e.codePoints().forEach(…)
的操作

如果使用上述方法之一,还需要将条目强制转换为chars,因为
codePoints()
chars()
返回IntStreams

正如@Holger在评论中提到的,我的第一个回答包含以下片段
Stream.of(e.getKey().toCharArray())
,它将为您提供一个带有单个
char[]
的流


当然,有更好的方法来做您想做的事情,但是您的问题是关于编译错误。

我假设,您的输入是一个包含所有字符的字符串。 因此,您可以跳过初始映射的创建,将字符串拆分为3块,将每个结果字符串映射到一个键,并使用一些公式计算值的差异

    String sampleString= "SOSSQRSOP";
    final char[] SOS = "SOS".toCharArray();
    Map<String, Integer> result = IntStream.rangeClosed(0, sampleString.length() / 3)
                                           .mapToObj(i -> sampleString.substring(3*i, Math.min(3*i+3, sampleString.length())))
                                           .filter(s -> !s.isEmpty())
                                           .collect(Collectors.toMap(s -> s,
                                                                     s -> (int) IntStream.range(0, s.length())
                                                                                         .filter(i -> SOS[i] != s.charAt(i))  
                                                                                         .count()));

    result.forEach((k,v) -> System.out.println(k + " -> " + v));
String sampleString=“SOSSQRSOP”;
最终字符[]SOS=“SOS”.toCharArray();
Map result=IntStream.rangeClosed(0,sampleString.length()/3)
.mapToObj(i->sampleString.substring(3*i,Math.min(3*i+3,sampleString.length()))
.filter(s->!s.isEmpty())
.collect(收集器).toMap(s->s,
s->(int)IntStream.range(0,s.length())
.filter(i->SOS[i]!=s.charAt(i))
.count());
result.forEach((k,v)->System.out.println(k+“->”+v));
关于您自己的实施:

for(int i=0; i< characters.length;i++){
   int index=0; //<-- this will always set the index to 0
   if(characters[i] != message[i]){
     messages.put(e.getKey(),++index); //<-- this sets the index to one before assigning it to the map entry value, resulting in being 1, always
   }
}
for(int i=0;i    String sampleString= "SOSSQRSOP";
    final char[] SOS = "SOS".toCharArray();
    Map<String, Integer> result = IntStream.rangeClosed(0, sampleString.length() / 3)
                                           .mapToObj(i -> sampleString.substring(3*i, Math.min(3*i+3, sampleString.length())))
                                           .filter(s -> !s.isEmpty())
                                           .collect(Collectors.toMap(s -> s,
                                                                     s -> (int) IntStream.range(0, s.length())
                                                                                         .filter(i -> SOS[i] != s.charAt(i))  
                                                                                         .count()));

    result.forEach((k,v) -> System.out.println(k + " -> " + v));
for(int i=0; i< characters.length;i++){
   int index=0; //<-- this will always set the index to 0
   if(characters[i] != message[i]){
     messages.put(e.getKey(),++index); //<-- this sets the index to one before assigning it to the map entry value, resulting in being 1, always
   }
}