Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.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
Java 我怎么能';中断';何时满足HashMap值中的第一次出现?_Java_Hashmap_Return - Fatal编程技术网

Java 我怎么能';中断';何时满足HashMap值中的第一次出现?

Java 我怎么能';中断';何时满足HashMap值中的第一次出现?,java,hashmap,return,Java,Hashmap,Return,在下面,您可以看到我的代码片段,我试图识别给定电话号码的来源国。问题是它总是返回比较字符串值的最后一个键 我已经按desc顺序按值对HashMap进行了排序,然后使用startWith方法将给定字符串与HashMap中的每个值进行了比较 import java.util.Comparator; import java.util.Map; import java.util.HashMap; import java.util.Map.Entry; import javax.swing.JOption

在下面,您可以看到我的代码片段,我试图识别给定电话号码的来源国。问题是它总是返回比较字符串值的最后一个键

我已经按desc顺序按值对HashMap进行了排序,然后使用startWith方法将给定字符串与HashMap中的每个值进行了比较

import java.util.Comparator;
import java.util.Map;
import java.util.HashMap;
import java.util.Map.Entry;
import javax.swing.JOptionPane;

public class CountryFinder {

    static Map<String, String> countriesNamesAndCodes;

    public static void main(String[] args) {

        countriesNamesAndCodes = new HashMap<>();
        countriesNamesAndCodes.put("Greece", "30");
        countriesNamesAndCodes.put("Italy", "39");
        countriesNamesAndCodes.put("Germany", "49");
        countriesNamesAndCodes.put("USA", "1");
        countriesNamesAndCodes.put("UK", "44");
        countriesNamesAndCodes.put("Bahamas", "1-242");
        countriesNamesAndCodes.put("ExampleCountry", "301");

        for (Entry<String, String> entry : countriesNamesAndCodes.entrySet()) {
            if (entry.getValue().contains("-")) {
                String tempValue = entry.getValue().replaceAll("-", "");
                entry.setValue(tempValue);
            }
        }

        countriesNamesAndCodes.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
                .forEach(System.out::println);

        String input = String.valueOf(JOptionPane.showInputDialog("Type a telephone number"));
        System.out.println(input);
        System.out.println("Origin Country: " + getCountry(input));

    }

    private static String getCountry(String telephoneNumber) {
        for (Entry<String, String> entry : countriesNamesAndCodes.entrySet()){
            if (telephoneNumber.startsWith(entry.getValue())) {
                return (entry.getKey());
            }
        }
        return null;
    }
}
import java.util.Comparator;
导入java.util.Map;
导入java.util.HashMap;
导入java.util.Map.Entry;
导入javax.swing.JOptionPane;
公共类CountryFinder{
静态地图国家编码;
公共静态void main(字符串[]args){
countriesNamesAndCodes=新HashMap();
countriesNamesAndCodes.put(“希腊”,“30”);
countriesNamesAndCodes.put(“意大利”、“39”);
国家名称和代码。put(“德国”、“49”);
国家名称和代码。put(“美国”、“1”);
countriesnamasandcodes.put(“英国”、“44”);
CountriesnamasandCodes.put(“巴哈马”,“1-242”);
countriesNamesAndCodes.put(“ExampleCountry”、“301”);
for(条目:countriesNamesAndCodes.entrySet()){
if(entry.getValue()包含(“-”){
字符串tempValue=entry.getValue().replaceAll(“-”,”);
entry.setValue(tempValue);
}
}
countriesNamesAndCodes.entrySet().stream().sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
.forEach(System.out::println);
字符串输入=String.valueOf(JOptionPane.showInputDialog(“键入电话号码”);
系统输出打印项次(输入);
System.out.println(“原产国:+getCountry(输入));
}
私有静态字符串getCountry(字符串电话号码){
for(条目:countriesNamesAndCodes.entrySet()){
if(telephoneNumber.startsWith(entry.getValue())){
return(entry.getKey());
}
}
返回null;
}
}

当输入为1242888999或1-242888999时,我预计输出为“巴哈马”,但实际输出为“美国”。输入301555666也是如此,我希望是“ExampleCountry”而不是“Greece”。

我不相信这一行会对
HashMap
进行排序:它只对打印流进行排序

countriesNamesAndCodes.entrySet().stream()
   .sorted(Map.Entry.comparingByValue(Comparator.reverseOrder()))
   .forEach(System.out::println);
这意味着,当您稍后循环映射的条目集时,您将受制于它在散列映射中的移动顺序,Java对该顺序不做任何保证(甚至说顺序可能会随时间而改变)


您可能需要查看一个。HashMap未排序。您不能依赖它的顺序,因为它主要基于
hashCode()

但是,您的问题与顺序无关,这是因为您没有选择最长的前缀(长度最高的值):如果您查找1-242,则USA(1)和巴哈马(1-242)有效。国家(301)和希腊(30)也是如此

您的算法应该是这样的:对于电话号码以条目值开头的每个条目,我们会记住“最佳匹配”条目,并在从未找到该条目(初始情况)或其值大于之前匹配的值时进行更新

private static String getCountry(String telephoneNumber) {
    var bestMatch = null; // Map.Entry<String,String>
    for (Entry<String, String> entry : countriesNamesAndCodes.entrySet()){
      if (telephoneNumber.startsWith(entry.getValue()) {
        if (bestMatch == null || entry.getValue().length() > bestMatch.getValue().length()) {
          bestMatch = entry;
        }
      }
    }
    return null != bestMatch ? bestMatch.getKey():null;
}
私有静态字符串getCountry(字符串电话号码){
var bestMatch=null;//Map.Entry
for(条目:countriesNamesAndCodes.entrySet()){
if(telephoneNumber.startsWith(entry.getValue()){
if(bestMatch==null | | entry.getValue().length()>bestMatch.getValue().length()){
最佳匹配=输入;
}
}
}
返回null!=bestMatch?bestMatch.getKey():null;
}

您的代码执行的正是其编写目的,您的问题就在这里

   private static String getCountry(String telephoneNumber) {
        for (Entry<String, String> entry : countriesNamesAndCodes.entrySet()){
            if (telephoneNumber.startsWith(entry.getValue())) {
                return (entry.getKey());
            }
        }
        return null;
    }
私有静态字符串getCountry(字符串电话号码){
for(条目:countriesNamesAndCodes.entrySet()){
if(telephoneNumber.startsWith(entry.getValue())){
return(entry.getKey());
}
}
返回null;
}
您正在提取第一个搜索匹配条目值,在您的情况下(1-242888999)以1开头,因此它将带来条目=1,即USA


原因是您正在使用现有的流进行排序,当您输入getCountry时,您再次失去了顺序,因此您需要先保存您的排序。

结合其他几个答案中的元素,您可能需要将
SortedMap
从国家代码保存到国家名称,并进行排序按长度降序排列(按字母顺序排列)

这样,最长的匹配总是先检查,所以您不会遇到相同的前缀问题

import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import static java.util.Map.Entry;
import static java.util.Comparator.comparingInt;
import static java.util.Comparator.naturalOrder;

class Example {
  public static void main(String[] args) {

    SortedMap<String, String> codeCountries = new TreeMap<>(
        comparingInt(String::length)
          .reversed()
          .thenComparing(naturalOrder()));

    codeCountries.putAll(Map.of(
        "1", "United States",
        "1241", "Bahamas",
    ));

    for (String name : codeCountries.values) {
        System.out.println(name);
        // Prints "United States", then "Bahamas"
    }
  }
}
import java.util.Map;
导入java.util.SortedMap;
导入java.util.TreeMap;
导入静态java.util.Map.Entry;
导入静态java.util.Comparator.comparingInt;
导入静态java.util.Comparator.naturalOrder;
课例{
公共静态void main(字符串[]args){
SortedMap codeCountries=新树映射(
比较(字符串::长度)

.然后比较(自然领主());
codeCountries.putAll(地图)(
“1”、“美国”,
“1241”、“巴哈马”,
));
for(字符串名称:codeCountries.values){
System.out.println(名称);
//打印“美国”,然后打印“巴哈马”
}
}
}
你唯一需要做的另一个改变是,在将破折号放入地图之前,你必须从国家代码中删除破折号。如果不删除,两个键都将保留在地图中

作为一个类似的、可能更快(但速度不会快到真正重要的程度)的替代方案,您可以保留一个未排序的地图,并将国家代码作为其键,并且每当您获得输入时,您可以尝试从地图中获取其所有前缀:

Map<String, String> countryCodes = Map.of("1242", "Bahamas", "1", "United States");

String input = /* get some input */;

for (int i = input.length; i > 0; --i) {
    String country = countryCodes.get(input.substring(0, i));
    if (country != null) {
        return country;
    }
}
// If you get here, no country code was found in the map.

// Alternatively, with streams:
IntStream.range(0, input.length())
  .mapToObj(i -> input.substring(0, input.length() - i))
  .filter(countryCodes::containsKey)
  .findFirst();
Map countryCodes=国家地图(“1242”、“巴哈马”、“1”、“美国”);
字符串输入=/*获取一些输入*/;
for(int i=input.length;i>0;--i)
    private static Map<String, String> sortMapByValuesDesc(Map<String, String> unsortedMap) {

    return sortedMap = unsortedMap
            .entrySet()
            .stream()
            .sorted(Collections.reverseOrder(Map.Entry.comparingByValue()))
            .collect(
                    toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e2, LinkedHashMap::new));

}