繁体   English   中英

将字符串转换为泛型类型<t extends comparable<t> &gt;</t>

[英]Casting a String to a generic type <T extends Comparable<T>>

我正在编写一个用于操作和显示二叉树的 GUI 客户端。 这里棘手的部分是树是通用类型。 我的情况是,我必须通过Message<T>向我的服务器传递一个从用户那里获得的值,它是一个可序列化的 object,用于存储请求及其对服务器的值。 我的问题是T类型的值是使用JOptionPane.showInputDialog获得的,它返回String

有没有办法以T类型的形式从用户那里获取输入或将String转换为提到的类型?

主要 Class:

import javax.swing.JOptionPane;

public class Main {

  public static void main(String[] args) {

    Object[] options = {"Integer", "Double", "String"};
    int result = JOptionPane
        .showOptionDialog(null, "Please, select the type of the tree:", "Selection of the type",
            JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, null);

    switch (result) {
      case 0:
        MyFrame<Integer> frameInteger = new MyFrame<>("Integer");
        frameInteger.setVisible(true);
        break;
      case 1:
        MyFrame<Double> frameDouble = new MyFrame<>("Double");
        frameDouble.setVisible(true);
        break;
      case 2:
        MyFrame<String> frameString = new MyFrame<>("String");
        frameString.setVisible(true);
      default:
        throw new IllegalArgumentException("Invalid type.");
    }
  }

}

JFrame/客户端 Class:

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class MyFrame<T extends Comparable<T>> extends JFrame {

  Socket client;
  JPanel context = new JPanel();
  String address;
  ObjectInputStream in;
  ObjectOutputStream out;
  BinaryTree<T> tree;
  boolean result;
  String type;

  public MyFrame(String type) {
    this.type = type;
    address = JOptionPane.showInputDialog("Please enter the address and port (e.g. 127.0.0.1:5555)");
    try {
      client = new Socket(address.split(":")[0], Integer.parseInt(address.split(":")[1]));
      in = new ObjectInputStream(client.getInputStream());
      out = new ObjectOutputStream(client.getOutputStream());
    } catch (Exception e) {
      System.err.println("It wasn't possible to obtain the address from the given input.");
    }

    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setSize(1024, 720);
    setLocationRelativeTo(null);
    setTitle("Binary Tree Client");

    initUI();
  }

  private void initUI() {
    JMenuBar menuBar = new JMenuBar();
    JMenu file = new JMenu("File...");
    JMenu edit = new JMenu("Edit");

    JMenuItem close = new JMenuItem("Close");

    JMenuItem insert = new JMenuItem("Insert...");
    JMenuItem delete = new JMenuItem("Delete...");
    JMenuItem search = new JMenuItem("Search...");

    close.addActionListener(e -> System.exit(0));

    insert.addActionListener(e -> {
      String value = JOptionPane.showInputDialog("Please insert the node value:");

      // here is the problem
      tree = exchange(new ClientMessage<T>("INSERT", value)).getTree();

    });

    file.add(close);

    edit.add(insert);
    edit.add(delete);
    edit.add(search);

    menuBar.add(file);
    menuBar.add(edit);

    setJMenuBar(menuBar);
  }

  public ServerMessage<T> exchange(ClientMessage<T> clientMsg) {
    try {
      out.writeObject(clientMsg);
      return (ServerMessage<T>) in.readObject();
    } catch (IOException | ClassNotFoundException e) {
      e.printStackTrace();
      return null;
    }
  }
}

客户端消息 Class:

import java.io.Serializable;

public class ClientMessage<T extends Comparable<T>> implements Serializable {

  private String request;
  private T value;

  public ClientMessage(String request, T value) {
    this.request = request;
    this.value = value;
  }

  public String getRequest() {
    return request;
  }

  public T getValue() {
    return value;
  }
}

我想在其中使用该值的ServerThread Class

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;

public class ServerThread<T extends Comparable<T>> extends Thread {

  BinaryTree<T> tree;
  ObjectInputStream in;
  ObjectOutputStream out;
  Socket client;

  public ServerThread(Socket client) {
    this.client = client;
  }

  @Override
  @SuppressWarnings("unchecked")
  public void run() {
    try {
      in = new ObjectInputStream(client.getInputStream());
      out = new ObjectOutputStream(client.getOutputStream());

      ClientMessage<T> request;
      ServerMessage<T> response = new ServerMessage<>();

      while ((request = (ClientMessage<T>) in.readObject()) != null) {
        handleRequest(request, response);

        response.setTree(tree);
        out.writeObject(response);
      }

    } catch (IOException | ClassNotFoundException e) {
      e.printStackTrace();
    }
  }

  private void handleRequest(ClientMessage<T> request, ServerMessage<T> response) {

    switch (request.getRequest()) {
      case "SET":
        tree = new BinaryTree<>();
        break;
      case "INSERT":
        tree.insert(request.getValue());
        break;
      case "DELETE":
        tree.delete(request.getValue());
        break;
      case "SEARCH":
        response.setResult(tree.search(request.getValue()));
        break;
      default:
        throw new IllegalArgumentException("Invalid request.");
    }
  }
}

更改您的MyFrame class 以接受Class<T>

Class<T> type;

public MyFrame(Class<T> type) {
  this.type = type;
  ...
}

并调用:

MyFrame<Integer> frameInteger = new MyFrame<>(Integer.class);

或者,由于您显然不使用type字段,只需删除type字段和构造函数参数,然后调用如下:

MyFrame<Integer> frameInteger = new MyFrame<>();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM