为什么 Java 中的最后一个地图元素不断重复

Why the last map element in Java repeated constantly

我在 Java 中的代码块下面有一些问题:

  1. 输出给新德里5倍。我想知道为什么其他地图元素没有列出,最后一个不断重复?输出为:

` 城市代码:DEL --> 城市名称:新德里

City Code: DEL --> City Name: New Delhi
City Code: DEL --> City Name: New Delhi
City Code: DEL --> City Name: New Delhi
City Code: DEL --> City Name: New Delhi
  1. 例如,如果用户在第一个输入中给出 3(对于元素的数量),则程序只需要 2 个元素到数组然后它就会停止。
  2. 这个代码块永远不会停止,我怎样才能停止程序?

代码块:

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

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



    ExecutorService executorService = Executors.newFixedThreadPool(5);

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

    City moscow = new Moscow("Moscow", "MOW");
    map.put(moscow.getCityCode(), moscow);
    City london = new London("London", "LON");
    map.put(london.getCityCode(), london);
    City newyork = new NewYork("New York", "NYC");
    map.put(newyork.getCityCode(), newyork);
    City berlin = new Berlin("Berlin", "BER");
    map.put(berlin.getCityCode(), berlin);
    City newdelhi = new NewDelhi("New Delhi", "DEL");
    map.put(newdelhi.getCityCode(), newdelhi);


    List<City> cityByCode = new ArrayList<>(map.values());
    Collections.sort(cityByCode);
    for (int i = 0; i < cityByCode.size(); i++) {
        System.out.println("City Code: " + City.getCityCode() + " --> City Name: " + City.getCityName());
    }


    Scanner s = new Scanner(System.in);
    System.out.println("Select a minimum of three and a maximum of five cities listed above. First of all, please specify the number of cities you will choose: ");
    int length = s.nextInt();
    System.out.println("Please enter " + length + " city codes ");
    String[] myArray = new String[length];
    for (int i = 0; i < length; i++) {
        myArray[i] = s.nextLine();
    }

    for (String list : myArray) {
        switch (list) {
            case "MOW":
                executorService.execute(new SimpleThread(moscow));
                break;
            case "LON":
                executorService.execute(new SimpleThread(london));
                break;
            case "NYC":
                executorService.execute(new SimpleThread(newyork));
                break;
            case "BER":
                executorService.execute(new SimpleThread(berlin));
                break;
            case "DEL":
                executorService.execute(new SimpleThread(newdelhi));
                break;
        }
    }
}

}

您没有公开足够的代码来解决您的具体问题。但这里有一些提示和一些示例代码。

我不是 Scanner 的专家,但您似乎应该使用 … s.next(); 而不是 … s.nextLine();

始终在您的应用程序结束之前关闭您的执行程序服务。否则后台线程池可能会无限期地继续下去,就像一个僵尸‍♂️。

使用现代 Java 可以缩短您的代码。例如 Map.of, switch expressions, and try-with-resources. The new record feature defines a class for immutable objects 在合成 getter、toStringequalshashCode 方法时。但这只是语法,概念与您的原始代码相同。

通常最好从输入 strip white-space。

default 添加到您的 switch 以捕获意外输入。

这是一个完整的示例应用程序,其代码与您的原始代码非常接近。

package work.basil.example;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class MapOut
{
    public static void main ( String[] args )
    {
        MapOut app = new MapOut();
        app.demo();
    }

    private void demo ( )
    {
        // ----------|  Data  |------------------------------------------
        record City( String name , String code )
        {
        }

        Map < String , City > map = Map.of(
                "MOW" , new City( "Moscow" , "MOW" ) ,
                "LON" , new City( "London" , "LON" ) ,
                "NYC" , new City( "New York" , "NYC" ) ,
                "BER" , new City( "Berlin" , "BER" ) ,
                "DEL" , new City( "New Delhi" , "DEL" )
        );
        System.out.println( "map = " + map );

        // ----------|  Action  |------------------------------------------
        ExecutorService executorService = null;
        try (
                Scanner scanner = new Scanner( System.in ) ;
        )
        {
            executorService = Executors.newFixedThreadPool( 5 );

            for ( String key : map.keySet() )
            {
                City city = map.get( key );
                System.out.println( "City code: " + city.code + " | name: " + city.name );
            }
            System.out.println( "Select a minimum of three and a maximum of five cities listed above. First of all, please specify the number of cities you will choose: " );
            int length = scanner.nextInt();
            System.out.println( "Please enter " + length + " city codes, pressing Return/Enter after each: " );
            List < String > inputCodes = new ArrayList <>( length );
            for ( int i = 0 ; i < length ; i++ )
            {
                String input = scanner.next();
                inputCodes.add( input.strip().trim() );
            }

            for ( String inputCode : inputCodes )
            {
                switch ( inputCode )
                {
                    case "MOW" -> executorService.submit( ( ) -> System.out.println( map.get( inputCode ).name ) );
                    case "LON" -> executorService.submit( ( ) -> System.out.println( map.get( inputCode ).name ) );
                    case "NYC" -> executorService.submit( ( ) -> System.out.println( map.get( inputCode ).name ) );
                    case "BER" -> executorService.submit( ( ) -> System.out.println( map.get( inputCode ).name ) );
                    case "DEL" -> executorService.submit( ( ) -> System.out.println( map.get( inputCode ).name ) );
                    default -> throw new IllegalStateException( "Expected city code: " + inputCode );
                }
            }
        }
        finally
        {
            if ( Objects.nonNull( executorService ) )
            {
                executorService.shutdown(); // Always shutdown your executor service. Otherwise it may continue indefinitely, like a zombie ‍.
            }
        }
    }
}

按照目前的写法,对输入代码做 switch 是没有意义的。我们可以删除 switch 并使用单行 executorService.submit( ( ) -> System.out.println( map.get( inputCode ).name ) );。但我假设您考虑了其他特定于代码的逻辑,所以我将 switch 留在原地。

当运行时,用户输入:2MOWLON

map = {MOW=City[name=Moscow, code=MOW], LON=City[name=London, code=LON], NYC=City[name=New York, code=NYC], DEL=City[name=New Delhi, code=DEL], BER=City[name=Berlin, code=BER]}
City code: MOW | name: Moscow
City code: LON | name: London
City code: NYC | name: New York
City code: DEL | name: New Delhi
City code: BER | name: Berlin
Select a minimum of three and a maximum of five cities listed above. First of all, please specify the number of cities you will choose: 
2
Please enter 2 city codes, pressing Return/Enter after each: 
MOW
LON
Moscow
London