Java Передача объекта в метод
У меня есть программа, которая позволяет пользователю выбирать между бинарным деревом поиска, деревом сплайнов и красным черным деревом. Я написал класс для дерева бинарного поиска, и теперь я работаю над деревом сплайнов, но я понял, что мой метод, взаимодействующий с пользователем, работает только с деревом бинарного поиска. Я настроил его так, чтобы он создавал экземпляр любого дерева, которое выберет пользователь, но в моем коде я использую только переменную, которая будет создана, если пользователь выберет двоичное дерево поиска. У меня вопрос: как я могу сделать так, чтобы я только создал экземпляр дерева, выбранного пользователем, и как я могу использовать только одну переменную, чтобы при вставке элементов или работе с деревом мне не приходилось добавлять больше условных операторов для разных деревьев?
это то, что у меня сейчас
import java.util.Scanner;
import java.lang.Math.*;
public class Driver1
{
public static void main(String[] args)
{
//local variables
String treeChoice = null;
String choice = null;
String choice2 = null;
String command = null;
int insertAmount = -1;
String pattern;
int height = -1;
int i = -1;
//BST<Integer> myTree = null;
//ST<Integer> mySTTree = null;
int num = 0;
//Scanners to take user input
Scanner input = new Scanner(System.in);
Scanner inputt = new Scanner(System.in);
System.out.println("Which tree would you like to test (BST, ST, RBT)? ");
treeChoice = input.nextLine();
//Based on user input either a BST, Splay Tree, or RBT will be initialized.
if("BST".equalsIgnoreCase(treeChoice))
{
BST<Integer> myTree = new BST<Integer>();
}
else if("ST".equalsIgnoreCase(treeChoice))
{
//System.out.println("Splay Tree not ready yet");
ST<Integer> mySTTree = new ST<Integer>();
}
else if("RBT".equalsIgnoreCase(treeChoice))
{
System.out.println("RBT not ready yet");
//RBT<Integer> myTree = new RBT<Integer>();
}
else
{
System.out.println("Invalid Entry");
}
//Ask user how many items to input
System.out.println("How many items would you like to insert? ");
insertAmount = input.nextInt();
//ask user if the items will be random or sorted
System.out.println("Pattern (random or sorted): ");
choice2 = inputt.nextLine();
//If random, create random numbers
if("random".equalsIgnoreCase(choice2))
{
for(i = 1; i <= insertAmount; i++)
{
myTree.insert((int)(Math.random()*1000000)+i);
}
}
//else fill the tree with numbers in order from 1 to the user limit
else if("sorted".equalsIgnoreCase(choice2))
{
for(i = 1; i <= insertAmount; i++)
{
myTree.insert(i);
}
}
//Keep asking users input on what to do to the tree until user says quit
while(command != "quit")
{
System.out.println(
"Next command (insert X, delete X, find X, height, quit)?");
command = inputt.nextLine();
if (command.startsWith("insert"))
{
num = Integer.parseInt(command.replaceAll("\\D", ""));
boolean result = myTree.insert(num);
if(result == false)
{
System.out.println("Item already present.");
}
}
else if(command.startsWith("delete"))
{
num = Integer.parseInt(command.replaceAll("\\D", ""));
boolean result = myTree.delete(num);
}
else if(command.startsWith("find"))
{
num = Integer.parseInt(command.replaceAll("\\D", ""));
boolean result = myTree.find(num);
if(result == true)
{
System.out.println("Item present.");
}
else
{
System.out.println("Item not present.");
}
}
else if(command.startsWith("height"))
{
System.out.println("Current height of tree " + myTree.height());
}
else if(command.startsWith("quit"))
{
break;
}
System.out.println();
}
}//Close main method
как вы видите, я заполняю только myTree, которое было бы создано, если бы пользователь выбрал bst. и в то время как цикл я работаю только на myTree.
Как я могу сделать это более универсальным или моей другой идеей было взять пользовательский ввод, а затем создать экземпляр этого дерева и затем передать экземпляр в отдельный метод, чтобы я все еще мог использовать только myTree, так как он будет ссылаться на экземпляр, который был передан в этот метод, но я не уверен, как передать экземпляр в другой метод. Этот способ кажется лучшим, но я не уверен
любая помощь приветствуется
1 ответ
Ваши деревья должны расширять общий базовый класс или, лучше сказать, реализовывать общий интерфейс, скажем, Tree
, который определяет методы, которые будут использоваться на всех деревьях (find
, insert
, delete
). Тогда у вас должна быть только одна переменная Tree myTree
которому вы назначаете фактический экземпляр типа, который выбирает пользователь.
Вы уверены, что вышеприведенный код работает, однако? Если вы делаете это
if("BST".equalsIgnoreCase(treeChoice))
{
BST<Integer> myTree = new BST<Integer>();
}
тогда переменная myTree
будет недоступен после }
потому что блок кода, в котором он объявлен, заканчивается там. Вы можете объявить переменную в одной точке и присвоить ей значение позже, например, так:
Tree<Integer> myTree;
if("BST".equalsIgnoreCase(treeChoice)) {
myTree = new BinarySearchTree<Integer>();
} else if("ST".equalsIgnoreCase(treeChoice)) {
myTree = new SplayTree<Integer>();
} else if("RBT".equalsIgnoreCase(treeChoice)) {
myTree = new RedBlackTree<Integer>();
} else {
throw new IllegalArgumentException(treeChoice + " is not a valid input");
}
Я очень рекомендую, чтобы вы давали своим классам настоящие имена, которые ясно показывают, что они представляют, а не просто двух- или трехбуквенные комбинации. Обратите внимание, что если вы не выбросите исключение в последнем else
В дальнейшем, компилятор будет жаловаться, что "переменная myTree, возможно, не была инициализирована".
В качестве альтернативы, вы можете поместить весь свой код после создания операторов if-else в метод, скажем, <T> void testTree(Tree<T> myTree)
и вызвать этот метод непосредственно, где вы оцениваете пользовательский ввод, например if("BST".equalsIgnoreCase(treeChoice)) testTree(new BinarySearchTree<Integer>());
, но в некоторых случаях вы захотите присвоить его переменной в любом случае.