Java语言怎么实现自动读取不同类型的变量并且切换不同类型的菜单

Java语言怎么实现自动读取不同类型的变量并且切换不同类型的菜单?菜单和类型的变量的输入联动,这个怎么用代码去实现的呢

代码如下


import java.util.Scanner;

public class VariableMenu {

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int menuOption;
        
        do {
            // 显示菜单选项
            System.out.println("请选择变量类型:");
            System.out.println("1. 整数");
            System.out.println("2. 浮点数");
            System.out.println("3. 字符串");
            System.out.println("0. 退出");
            
            // 读取用户选择的菜单选项
            menuOption = scanner.nextInt();
            
            // 根据用户选择的菜单选项执行相应的操作
            switch (menuOption) {
                case 1:
                    readIntVariable();
                    break;
                case 2:
                    readFloatVariable();
                    break;
                case 3:
                    readStringVariable();
                    break;
                case 0:
                    System.out.println("程序已退出!");
                    break;
                default:
                    System.out.println("无效的选择,请重新输入!");
                    break;
            }
        } while (menuOption != 0);
        
        scanner.close();
    }
    
    // 读取整数类型的变量
    public static void readIntVariable() {
        Scanner scanner = new Scanner(System.in);
        
        System.out.println("请输入整数变量:");
        int intValue = scanner.nextInt();
        System.out.println("您输入的整数是:" + intValue);
        
        // 执行其他操作
        
        scanner.nextLine(); // 清空输入缓冲区的换行符
    }
    
    // 读取浮点数类型的变量
    public static void readFloatVariable() {
        Scanner scanner = new Scanner(System.in);
        
        System.out.println("请输入浮点数变量:");
        float floatValue = scanner.nextFloat();
        System.out.println("您输入的浮点数是:" + floatValue);
        
        // 执行其他操作
        
        scanner.nextLine(); // 清空输入缓冲区的换行符
    }
    
    // 读取字符串类型的变量
    public static void readStringVariable() {
        Scanner scanner = new Scanner(System.in);
        
        System.out.println("请输入字符串变量:");
        String stringValue = scanner.nextLine();
        System.out.println("您输入的字符串是:" + stringValue);
        
        // 执行其他操作
    }
}

要实现自动读取不同类型的变量并切换不同类型的菜单,你可以使用Java的输入输出和条件语句来实现。下面是一个示例代码,演示了如何根据不同的变量类型展示不同的菜单,并根据用户选择进行相应的操作:

import java.util.Scanner;

public class MenuExample {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        // 显示菜单选项
        System.out.println("请选择变量类型:");
        System.out.println("1. 整数");
        System.out.println("2. 浮点数");
        System.out.println("3. 字符串");

        // 获取用户选择
        int choice = scanner.nextInt();
        scanner.nextLine(); // 读取换行符

        // 根据选择展示不同的操作菜单
        switch (choice) {
            case 1:
                System.out.println("请输入整数变量:");
                int intValue = scanner.nextInt();
                scanner.nextLine(); // 读取换行符

                // 在这里执行针对整数变量的操作
                System.out.println("您输入的整数是:" + intValue);
                break;
            case 2:
                System.out.println("请输入浮点数变量:");
                double doubleValue = scanner.nextDouble();
                scanner.nextLine(); // 读取换行符

                // 在这里执行针对浮点数变量的操作
                System.out.println("您输入的浮点数是:" + doubleValue);
                break;
            case 3:
                System.out.println("请输入字符串变量:");
                String stringValue = scanner.nextLine();

                // 在这里执行针对字符串变量的操作
                System.out.println("您输入的字符串是:" + stringValue);
                break;
            default:
                System.out.println("无效的选择");
                break;
        }

        scanner.close();
    }
}

这段代码首先展示了一个选择菜单,用户可以选择不同的变量类型。根据用户的选择,程序会要求用户输入相应类型的变量。然后,根据变量类型执行相应的操作。

需要注意的是,这段代码只是一个简单示例,实际应用中你可能需要增加更多的错误处理和逻辑。希望这个示例能帮助到你!

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/1073714
  • 这篇博客你也可以参考下:Java接口有多个实现类,根据不同的业务场景创建不同的实现类实例
  • 同时,你还可以查看手册:java-学习Java语言 - 描述Java编程语言的基本概念和特点的课程。-类和对象》描述了如何编写创建对象的类,以及如何创建和使用对象。-更多关于课程的信息 中的内容
  • 您还可以看一下 汪翠老师的java项目实战之欢乐斗地主游戏开发教程 毕业项目课程设计带源码课程中的 接收从服务器端群发回来的消息并添加地主牌小节, 巩固相关知识点
  • 除此之外, 这篇博客: java模拟浏览器与服务器请求与响应的过程中的 服务器端接收解析请求,查找资源并返回响应信息 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:

    我们创建一个类(Server)来表示服务器
    首先在Server类中写一个方法 startServer() 来表示启动一个服务器
    此时,我们发现一个可以优化的点:
    在未来的使用中,有可能我们的端口号不是固定的,所以,我们将端口号单独的放在一个配置文件中server.properties,在启动服务器时,我们先读取一遍配置文件,在配置文件中找到需要的端口号,以后只需要改配置文件就可以了。

    port=9999

    接下来我们创建一个类ServerFileReader ,这个类中我们读取这个server.properties的配置文件,这个ServerFileReader类中运用了一个缓存机制,避免每一次获取端口号都需要读取一次配置文件,回降低性能,所以在每次类加载之前,用静态代码块先读取一次配置文件中的信息,将这些信息全部存到一个Map集合中,以后在每次需要获取端口号的时候,就不用再使用I/O去读取配置文件了,直接去访问这个Map集合就可以了。

    public class ServerFileReader {
    
        private static HashMap<String,String> map = new HashMap<>();
    
        static {
            try {
                Properties prop = new Properties();
                prop.load(new FileReader("src/server.properties"));
                Enumeration en = prop.propertyNames();
                while (en.hasMoreElements()){
                    String key = (String) en.nextElement();
                    String value = prop.getProperty(key);
                    map.put(key,value);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static String getValue(String key){
            return map.get(key);
        }
    }
    

    然后我们在每次启动服务器的时候获取端口号就调用这个getValue()方法,再通过Integer.parseInt()方法将这个端口号字符串转化成int类型

    	public void startServer(){
            try {
                System.out.println("========启动服务器========");
                //获取端口号
                int port = Integer.parseInt(ServerFileReader.getValue("port"));
                //创建一个服务
                ServerSocket serverSocket = new ServerSocket(port);
                while(true){
                    //等待某一个客户端过来连接,如果连接到了就会产生一个socket对象
                    Socket socket = serverSocket.accept();
                    //启动一个线程,负责处理当前浏览器发送过来的消息
                    ServerHandler handler = new ServerHandler(socket);
                    handler.start();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    

    由于服务器和浏览器之间存在一种一对多的关系(多个浏览器可以同时访问一个服务器),这里为了避免第二个用户访问是资源被占用的问题,我们创建一个线程对象ServerHandler来处理多线程并发的问题。ServerHandler类首先继承Thread类变成一个线程对象。然后再重写run()方法。当然为了接收刚才在浏览器端传输过来的数据,我们需要一个Socket对象当做属性,再提供一个构造方法。在服务器端有一个方法会等待一个客户端过来连接,serverSocket.accept()方法会返回一个Socket对象,这个Socket对象就是刚才浏览器端发送请求的那个Socket对象了

    	public class ServerHandler extends Thread{
    	    private Socket socket;
    	
    	    public ServerHandler(Socket socket) {
    	        this.socket = socket;
    	    }
    	
    	    public void run(){
    	    }
        }
    

    在这个线程对象ServerHandler类中我们需要完成以下这几件事情。

    1. 接收请求
    2. 解析内容和参数
    3. 将服务器响应的内容写回浏览器
    	private void receiveRequest(){
            try {
                InputStream is = socket.getInputStream();//最基本的字节流
                InputStreamReader isr = new InputStreamReader(is);//将字节流转化成字符流
                BufferedReader reader = new BufferedReader(isr);//将字符流包装成高级流,缓冲流,可以读取一行消息
                String contentAndParams = reader.readLine();
                //接受到浏览器发送过来的请求后,开始调用下一个方法(解析内容和参数)
                this.parseContentAndParams(contentAndParams);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
    	private void parseContentAndParams(String contentAndParams){
            //创建两个变量分别存储content和params
            String content = null;
            HashMap<String,String> paramsMap = null;
            //按照?将contentAndParams拆开
            //?前面的部分是content  ?后面的部分是params
            //按照问号将其拆分
            String[] arr = contentAndParams.split("\\?");
            if(arr.length == 2){
                //如果有携带问号,content就是问号前面部分
                //再将问号后面部分的每一个key=value处理好后存入paramsMap集合
                content = arr[0];
                String params = arr[1];
                String[] keyAndValues = params.split("&");
                paramsMap = new HashMap<>();
                for (String keyAndValue : keyAndValues) {
                    String[] kv = keyAndValue.split("=");
                    paramsMap.put(kv[0],kv[1]);
                }
            }else{
                //如果没有问号,那么整个部分都是content
                content = arr[0];
            }
            //---------------至此,浏览器传输过来的信息已经解析完毕-------------
            //创建两个对象,一个对象是包含所有请求信息的,另一个对象是为了接收响应回来的结果
            //传递给你的是空对象,在控制层执行完毕后将这个对象填满
            HttpServletRequest request = new HttpServletRequest(content,paramsMap);
            HttpServletResponse response = new HttpServletResponse();
            ServletController.findController(request,response);
            //---------------程序执行到这里,证明response对象已经被填满了-----------
            this.responseToBrowser(response);
        }
    

    注意:当服务器解析完成后得到了一个字符串content和一个paramsMap集合。我们需要通过这两个参数去找到具体的控制层去执行相应的事情,此时为了参数传递方便以及为了方便后续代码的维护,我们创建了一个HttpServletRequest对象去存储这个content和paramsMap

    public class HttpServletRequest {
        //创建一个类,用来储存浏览器发送过来的请求信息
        private String content;
        private HashMap<String,String> paramsMap;
    
        public HttpServletRequest(String content, HashMap<String, String> paramsMap) {
            this.content = content;
            this.paramsMap = paramsMap;
        }
    
        public HttpServletRequest() {
        }
    
        /**
         * 获取paramsMap集合中的值,根据具体哪一个键就可以取出与之对应的值了
         * @param key 键
         * @return 返回与该key对应的值
         */
        public String getParameter(String key){
            return this.paramsMap.get(key);
        }
    
        public String getContent() {
            return content;
        }
        public void setContent(String content) {
            this.content = content;
        }
        public HashMap<String, String> getParamsMap() {
            return paramsMap;
        }
        public void setParamsMap(HashMap<String, String> paramsMap) {
            this.paramsMap = paramsMap;
        }
    }
    

    当然,找到对应的控制层Controller之后,需要将他们执行完毕后的结果返回给ServerHandler对象,这里我们不用再findController()方法上设计返回值,我们直接在调用这个findController()方法的时候传递一个HttpServletResponse 对象,(注意:此时传递的HttpServletResponse 对象是一个空对象,没有任何东西,我们之所以可以利用这种方式来接收返回值的目的是因为HttpServletResponse 对象本身就是一个应用数据类型,我们可以在方法执行完毕后将这个对象填满,就可以接收到返回值了)
    我们在这个HttpServletResponse类中提供了几个方法,可以调用这个write()方法将响应信息写出去。

    //创建一个类,用来储存服务器响应回来的信息
    public class HttpServletResponse {
    
        //创建一个StringBuilder处理字符串
        private StringBuilder responseContent = new StringBuilder();
    
        public void write(String str){
            this.responseContent.append(str);
        }
    
        public String getResponseContent(){
            return this.responseContent.toString();
        }
    }
    

    也可以通过读取一个文件的方式(可以将响应信息提前写到一个路径下的文件中去)然后通过I/O去读取这个文件,将这个文件中的信息每一行字符串写回去,这个文件目前我们暂时用index.view的方式描述,当然这个文件就是将来我们的jsp文件或者是html文件,这个文件中有可能携带有一些特殊含义的符号,当响应回浏览器后再在浏览器进行解析响应回去的字符串,然后展示,呈现在用户眼前。

    	public void sendRedirect(String filePath){
            BufferedReader reader = null;
            try {
                File file = new File("src/file/"+filePath);
                reader = new BufferedReader(new FileReader(file));
                String value = reader.readLine();
                while(value != null){
                    this.responseContent.append(value);
                    value = reader.readLine();
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    if (reader != null) {
                        reader.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    

    现在,我们已经写好了HttpServletRequest这个类和HttpServletResponse这个类,可以去调用findController()这个方法,由于findController()这个方法做的事情,与这个ServerHandler类中的方法做的事情有些不一致,我们将其抽离出去形成一个新的类ServletController,在ServerHandler类中写一个findController()方法去找寻与资源名对应的控制层(通过反射机制)
    注意:(由于我们在浏览器端输入的URL地址串中的每一个符号都有特殊意义,点号代表所表示文件的后缀名,表示文件类型,所以我们在输入URL地址串的时候只能输入资源的名字和后缀名,还不能输入这个资源对应的Controller控制层具体在哪一个包下,但是,如果通过反射机制Class.forName()方法去加载类的时候是必须要传递一个类全名给他的,所以我们只能用过使用配置文件的方式将资源名与之对应的Controller的类全名写到配置文件中,这里我们定义了一个web.properties的配置文件)

    index=controller.IndexController
    login=controller.LoginController

    然后我们有了这个配置文件,就可以每次通过资源名,参考配置文件中与资源名相对应的类全名去找到具体对应的Controller类,从而就可以通过反射机制,去加载找到该类了
    但是此时出现了两个可以优化的点:
    1、我们每次在执行findController方法的时候都会去读取一次配置文件,这样会大大降低程序的性能,所以我们在这个类中增加一个缓存机制,就是在每次类加载之前就将配置文件中的信息全部读取一个,存储到一个Map集合中,我们以后执行findController()方法的时候就可以不再需要读取配置文件了,直接在这个Map集合中去找,这样就可以优化一下性能的问题。

    	static{
            try {
                Properties prop = new Properties();
                prop.load(new FileReader("src/web.properties"));
                //将配置文件中的信息全部读取出来放入到controllerNameMap集合中
                Enumeration en = prop.propertyNames();
                while (en.hasMoreElements()){
                    String content = (String)en.nextElement();
                    String realControllerName = prop.getProperty(content);
                    controllerNameMap.put(content,realControllerName);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    

    2、我们发现Controller对象与之前我们写的Service和Dao的对象特别相似,里面只有方法在做事情,没有属性,所以我们可以考虑将每一个Controller对象设计成一个单例模式,就是每次在找到一个Controller对象的时候,我们就可以将这个对象存到Map集合中,下一次要使用这个Controller对象的时候,就可以直接在这个Map集合中去取就行了。
    最后我们,整理优化一下findController()方法:

    	public static void findController(HttpServletRequest request,HttpServletResponse response){
            //获取资源名
            String content = request.getContent();
            try {
                //获取这个类的对象
                HttpServlet controllerObject = controllerObjectMap.get(content);
                //如果对象不存在,证明之前没有使用过这个类,那就再通过反射的方式
                //参考配置文件(缓存)去创建一个该类的对象
                if(controllerObject == null){
                    //参考配置文件(缓存),找到真实的类名
                    String realControllerName = controllerNameMap.get(content);
                    //判断请求的真实名字是否存在,如果请求的真实名字也不存在,就不处理了
                    if(realControllerName != null){
                        //如果存在就通过反射区找到这个类
                        Class clazz = Class.forName(realControllerName);
                        //创建一个该类的对象
                        controllerObject = (HttpServlet) clazz.newInstance();
                        //将新创建的类对象放入集合中,下一次使用就不用创建对象了
                        controllerObjectMap.put(content,controllerObject);
                    }else{
                        throw new ClassNotFoundException();
                    }
                }
                //-------------以上可以确保controllerObject对象肯定存在---------------
                //通过反射获取这个类中的对应方法
                Class controllerClass = controllerObject.getClass();
                Method serviceMethod = controllerClass.getMethod("service", HttpServletRequest.class, HttpServletResponse.class);
                //找到对应的方法后就执行这个方法
                serviceMethod.invoke(controllerObject,request,response);
            } catch (ClassNotFoundException e) {
                response.write("请求的"+content+"Controller找不到");
            } catch (NoSuchMethodException e) {
                response.write("405 没有可以执行的方法");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    

    现在我们通过findController()方法找到了资源名对应的Controller控制层,所以我们就可以通过这个控制层去找到我们要响应给浏览器的内容。
    此时我么通过控制层找到了要响应的内容,我们提前把这些内容写到了文件中。现在我们只需要读取文件,把文件中的内容字符串,这些字符串就是即将要写回浏览器的响应信息,我们把这些信息存到HttpServletResponse对象中,此时这个HttpServletResponse的内容不再为空了。
    我们模拟了一个简单的html语句,表示控制层对应的响应信息

    欢迎进入银行系统<br>
    <form action="login" method="get">
    请输入用户名<input name="username" value=""><br>
    请输入密码<input name="password" value=""><br>
    感谢使用,再见
    

    我们单独设计一个方法,将刚才的HttpServletResponse对象传递给这个方法,我们将这里面的内容字符串(响应信息),响应给浏览器

    	private void responseToBrowser(HttpServletResponse response){
            try {
                PrintWriter out = new PrintWriter(socket.getOutputStream());
                out.println(response.getResponseContent());
                out.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    

    现在,我们通过输入了URL地址串,浏览器初步解析了这个URL地址串中的ip和端口号,通过ip和端口号创建了一个Socket对象,访问了服务器,服务器对这个资源名和参数做了进一步解析,得到了具体的资源名和参数,通过资源名找到了对应的控制层,从而找到了对应的响应信息,服务器也将响应信息写回浏览器了。我们现在回到浏览器这一端,将服务器响应给我们的信息做一个解析。
    此时,由于我们模拟的响应信息是一个html标签的内容,所以我们根据html标签的规则对这些字符串进行进一步解析


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^

要实现自动读取不同类型的变量并切换不同类型的菜单,您可以使用Java中的条件语句(如if-else语句或switch语句)来根据输入的变量类型来执行不同的操作。
首先,您需要定义一个变量来存储用户输入的值,例如:

String input = scanner.nextLine();

接下来,您可以使用if-else语句或switch语句来检查输入的值的类型,并根据类型执行不同的操作。例如:
使用if-else语句:

if (input.matches("\\d+")) {  
   // 执行数字类型操作  
} else if (input.matches("[a-zA-Z]+")) {  
   // 执行字母类型操作  
} else {  
   // 执行其他类型操作  
}

使用switch语句:

switch (input) {  
   case "数字":  
      // 执行数字类型操作  
      break;  
   case "字母":  
      // 执行字母类型操作  
      break;  
   default:  
      // 执行其他类型操作  
      break;  
}

在上述示例中,我们使用了正则表达式来检查输入的值是否为数字或字母。如果输入的值不是数字或字母,则视为其他类型。
在执行每种类型的操作后,您可以根据需要返回到菜单,让用户选择下一个操作。您可以使用循环语句(如while循环)来实现这个功能。
例如:

while (true) {  
   // 显示菜单  
   System.out.println("请选择操作:");  
   System.out.println("1. 数字操作");  
   System.out.println("2. 字母操作");  
   System.out.println("3. 其他操作");  
         // 获取用户选择  
   int choice = scanner.nextInt();  
         // 根据用户选择执行相应的操作  
   switch (choice) {  
      case 1:  
         // 执行数字类型操作  
         break;  
      case 2:  
         // 执行字母类型操作  
         break;  
      case 3:  
         // 执行其他类型操作  
         break;  
      default:  
         // 提示用户输入无效的选择  
         break;  
   }  
}

在上述示例中,我们使用while循环来不断显示菜单并等待用户选择。根据用户选择,我们使用switch语句执行相应的操作。如果用户输入无效的选择,则提示用户重新输入。