How to print a specific instance of an object using toString - java

How would I print and specific instance of an object using a toString?
So basically the user is inputing information. based on the input it will either saved in instance A or Instance B. Both instance A and B are subclasses with overriding toString methods. so the input from the user is saved in an array. How can I make it so that all the inputs that was an instance of A will print?
This is the code I currently have and it is not working.
public static void printA(ABC[] inputs)
{
for(int i = 0; i < inputs.length; i++)
{
if(inputs[i] instanceof A)
{
JOptionPane.showMessageDialog(null, inputs.toString());
}
}
}

you just need is
JOptionPane.showMessageDialog(null, inputs[i].toString());
cuz you are trying to show the array.toString() not the value you want to.

You are iterating inputs, but testing clients. This is why I prefer to use a for-each loop and I suggest you use a StringBuilder to build a single message and then display it once. Something like,
public static void printA(ABC[] inputs) {
StringBuilder sb = new StringBuilder();
for (ABC input : inputs) {
if (input instanceof A) {
sb.append(input).append(System.lineSeparator());
}
}
JOptionPane.showMessageDialog(null, sb.toString().trim());
}
Edit
The output you're getting ("LClient;#20d9896e") is because you are displaying inputs.toString(). Array doesn't override toString(), you can use Arrays.toString(Object[]) like
String msg = Arrays.toString(inputs);
But you'll get all of the items in the array. Also, make sure Client overrides toString().

Related

Calling an arrayList from another class which is private

I am trying to display an arraylist in a gui. However I am getting some troubles. I need to check if my game is legal, if it is not legal then it calls getProblems which displays the arraylist. I tried to call getProblems directly in the GUI class however it will show the array as empty. (Since it's not checking if it's legal). I also tried to call isLegal then getProblems but you cannot do this in a JOptionPane. Any tips on how I can call it accross?
GetProblems class
protected List < String > getProblems() {
return displayOutput;
}
IsLegal Class
public boolean isLegal() {
boolean legality;
if (checkRowConstraints().isEmpty()) {
legality = true;
} else {
getProblems();
legality = false;
}
return legalCheck;
}
GUI:
public void actionPerformed(ActionEvent e) {
if (!(puzzle.isLegal())) {
JOptionPane.showMessageDialog(FutoshikiFrame.this,
puzzle.getProblems(),
"You made a mistake!",
JOptionPane.INFORMATION_MESSAGE);
Here is difference between Actual display of GUI result and result i'm trying to get.
Further Problem found:
I need to return the arraylist then empty it. Fixed
Presently, there is an implicit call to the List's toString() method when you call puzzle.getProblems() within the JOptionPane. So rather than get the contents of the List, which is what you want, you're getting whatever toString() is giving you.
You're not going to get the contents of the List unless you iterate over it first.
You could try something like this. (Note, this is untested code. For demo purposes.)
String formattedString = "";
//let's iterate over our List and build a formatted string for output
for(String element : puzzle.getProblems())
{
formattedString += element;
}
Then you can output this formatted String
public void actionPerformed(ActionEvent e) {
if (!(puzzle.isLegal())) {
JOptionPane.showMessageDialog(FutoshikiFrame.this,
formattedString,
"You made a mistake!",
JOptionPane.INFORMATION_MESSAGE);

Using the Scanner class to read a scanner string

I have a problem creating a student class which contains a constructor which takes a Scanner string of a format "Brookes 00918 X12 X14 X16 X21". The conditions should be that there should be a student name and student number and the course codes should start with an "X". I have thrown IncorrectFormatExceptions in the case that they are not satisfied. However when I create a test class and enter a string and press enter , for example "abc 123" it doesn't produce an output which is usually the case.
Update: I've changed the code to use a String array tokens however now with the toString() method using "123 abc X12" it gives a Null Pointer Exception. It works when I put "123 abc" in the constructor
Update:Seems to work now forgot to initialize the arrayList
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Student extends UniversityPerson{
private String studentNumber="";
private List<String> courses=new ArrayList<String>();
private String studentName="";
public int checkNoofletters(char[] chararray){
int noofletters=0;
for (char c:chararray){
if (Character.isLetter(c)){
noofletters++;
}
}
return noofletters;
}
public String courseListinStr(){
String stringo="";
for (String c:courses){
stringo+=c;
stringo+=" ";
}
return stringo;
}
public Student(Scanner scanner) throws IncorrectFormatException{
int studentNumberCount=0;
int studentNameCount=0;
Scanner s=scanner;
String input=s.nextLine();
String[] tokens=input.split("\\s");
for (int i=0; i<tokens.length; i++){
char[] chars=tokens[i].toCharArray();
if (checkNoofletters(chars)==chars.length){//if the number of letters is equal to the character length
if (studentNameCount==1){throw new IncorrectFormatException("Can only have 1 student name");}
studentNameCount++;
this.studentName=tokens[i];
continue;
}
if (tokens[i].matches("[0-9]+")){//add to the studentNumbers list
if (studentNumberCount==1){throw new IncorrectFormatException("Can only have 1 student number");}
studentNumberCount++;
this.studentNumber=tokens[i];
continue;
}
if (!tokens[i].startsWith("X")){
throw new IncorrectFormatException("Course code must start with an 'X'");
}
System.out.println(tokens[i]);
courses.add(tokens[i]);
}
if (studentNumber=="" || studentName==""){
throw new IncorrectFormatException("Must have 1 student Number and Student Name");
}
}
#Override
public String toString() {
//return String.format("%s %s", studentName,courseListinStr());
return String.format("Student: %s %s", studentName,studentNumber);
}
#Override
public boolean equals(Object o) {
// TODO Auto-generated method stub
return false;
}
}
The best way would be to do something like this:
Scanner s=scanner;
String input = s.nextLine();
String[] tokens=input.split("\\s");
Now you can test all your conditions:
if (tokens.size() < yourNumber) throw new Exception("add here");
if (tokens[2].charAt(0)!='X') throw new Exception("add here");
and so on; it should be rather easy to create your Student Object based on your requirements.
Your program is full of errors and I'll list some of them after answering why it doesn't print anything: if you dump all threads you'll see that the main thread is stuck at next(), which blocks until next token is available, and effectively never leaves the constructor of the first student
if (s.hasNextInt()){
studentNumbers.add(s.nextInt());
s.next();
continue; // <--------- this line
}
I think this is not the only error in your program, so maybe you'd better throw the entire parsing away and restart from scratch.
You should create exactly one Scanner object for each input stream, not one for parsed object
You should not pass the scanner to the Student constructor
You should not put any algorithm in a constructor: make a separate object instead
To simplify your program introduce a Parser class
public class Parser {
public Parser(Reader in) {}
public boolean hasNext() {}
public Student next() {}
}
and inside next() make the parser deal with entire lines (Scanner.hasNextLine and Scanner.nextLine()) instead of individual tokens, otherwise you'll have to define a custom protocol to mean EOR (end of record)
Dealing with lines is easier to think about, program and test. Once you have the full record, you can further tokenize it with a simple String.split(), or directly use regular expressions.
I didn't go through, your whole code. But, I would suggest you to use StringTokenizer or split function and store it in temp array. Then, traverse through your temp array and validate the data.

Why am I getting extra stuff when looping through methods?

Okay not sure what is going on. I am using Java Reflection and iterating and inspecting methods of a particular class. Below is the following code I am using:
public void test(){
Class useCases = Car.class;
Method[] methods = useCases.getMethods();
Integer[] numbers = {2, 5};
String[] numberStrings = {"2", "5"};
for(int i=0; i<methods.length; i++){
try {
System.out.print(methods[i].getName());
Method method = useCases.getMethod(methods[i].getName(), new Class[]{String.class, Integer.class});
Object returnV = method.invoke(new Car(), numberStrings[i], numbers[i]);
System.out.print(returnV.toString() + "\n");
} catch (Exception e) {
e.printStackTrace();
}
}
}
Car Class:
public String getNumber(String number, Integer times){
return times == 2 ? number : null;
}
public String getNumber1(String number, Integer times){
return times == 5 ? number : null;
}
It loops through fine printing out the first two methods and the return value fine, but then it continues and prints out a wait() and not sure why and I am getting the following error:
java.lang.NoSuchMethodException: sample.Car.wait(java.lang.String,
java.lang.Integer)
Any help as to why the loop does not end with just printing and returning the values for the only two methods in that Car class.
getMethods returns all public methods available for class, including the ones inherited like wait() toString() which as you see don't accept (String, Integer) arguments, which is why
useCases.getMethod(methods[i].getName(), new Class[]{String.class, Integer.class});
is not able to find wait(String, Integer).
To get only methods declared in Car class use getDeclaredMethods instead.
BTW: instead of
System.out.print(returnV.toString() + "\n");
which will throw NullPointerException on returnV.toString() if returnV will be null use
System.out.println(returnV); // also you don't need to explicitly add `\n`,
// use println will add used by current OS line
// separator for you automatically
Every Class is implicitly extending Object, so you get all methods containing in Object too.

Checking if String Array is filled or empty

Hope this is not a duplicate because I already looked up some thread incl. this one, but it didn't help me.
My program is reading in some arguments that are optional by the user. They can add a rule to the game but don't have to.
I know that the rule will be containing 5 Numbers. I wanted to save them in a String Array with 5 spots so I can use them later. If the user won't enter a rule there will be a specific rule taken.
String[] rule = new String[5];
//reading in the program arguments and stuff..
//here I want to check whether the rule is taken from the user or not
//don't want to check with a boolean check
if (rule[0].equals("")) {
String[] newRule = "270-90-315-45-90".split("-");
for (int i = 0; i < newRule.length; i++) {
rule[i] = newRule[i];
}
}
Already tried this:
rule[0].equals("")
rule[0].equals(null)
rule[0].equals("null")
rule[0].matches("")
rule[0].matches("null")
rule.length == 0
rule.equals(null)
But I always get a NullPointerException or the if case will be skipped (length == 0)
Hopeyou can help me.
You didn't have tried the obvious?
if (rule[0] == null) {
Insted of using an fixed array, try using an ArrayList and add the values to the list. The ArrrayList-class will adjust the length of the list automaticly.
Example:
ArrayList<String> rules = new ArrayList<>();
if (rules.size() == 0) {
String[] newRule = "270-90-315-45-90".split("-");
//Instead of newRule.length as a comparison, use the
//number of rules with a number. Or use a foreach-loop
//if the number of rules may vary
for (int i = 0; i < 5; i++) {
rules.add(newRule[i]);
}
}
In the example you provide us with, rule[0] contains the value null which you can see yourself by adding the following line of code:
System.out.println(rule[0]==null);
returns true (try it !)
if (rule[0]==null) {
will return true and get inside the for loop if that is what you want.. See the following class which you can compile (using javac myEmpty.java) and run (using java myEmpty):
class myEmpty {
public static void main(String[] args) {
String[] rule = new String[5];
System.out.println(Arrays.toString(rule));
//reading in the program arguments and stuff..
//here I want to check whether the rule is taken from the user or not
//don't want to check with a boolean check
System.out.println(rule[0] == null);
if (rule[0] == null) {
//if ("".equals(rule[0])) {
String[] newRule = "270-90-315-45-90".split("-");
System.out.println(Arrays.toString(newRule));
for (int i = 0; i < newRule.length; i++) {
rule[i] = newRule[i];
System.out.println(rule[i]);
}
}
}
}
YOUR if if (rule[0].equals("")) { fails simply because rule[0] does not contain the value "" which you are checking for ! Keep in mind that "" and null are not the same, and use your if clauses accordingly !
So you want to change indices entered by user only.
The best way to do this would be to initialize the array with default values, then override those specified by the user.
String[] rule = "270-90-315-45-90".split("-");
// Now read "program arguments and stuff"
The NullPointerException I imagine is coming from the fact you have created an array of strings but have not initialized them with any values. They will default to null if you don't give them a value...hence the NPE.
Depending on where you are getting your input you could do something like this;
private static final String[] DEFAULT_RULES = {"270", "90", "315", "45","90" };
private static String[] rules;
public static void main(String[] args){
if(!isValidRule(args)){
// Potentially also check that the args are digits
throw new IllegalArgumentException("Must contain 5 rules");
}
rules = (args.length > 0) ? args : DEFAULT_RULES; // Used brackets on the ternary operator here for readability. Not essential.
...
}
private static boolean isValidRule(String[] rules){
return rules.length > 0 && rules.length != 5;
}
If you are working with some other non-static method thats taking the input, the same applies. You can perform your string split to get an array based on the delimiter you have specified and then do the same thing.
I don't imagine you would want to be passing around a string containing only hyphens if no rules are passed? Which is what you are hinting at by attempting to check if a string is empty after the split is performed.
Also if you want to check if the string contains characters or not use the isEmpty() method. It returns true if the length is 0 else it returns false. This already achieves what you are needlessly attempting.
In each of your tried options
rule[0].equals("")
rule[0].equals(null)
rule[0].equals("null")
rule[0].matches("")
rule[0].matches("null")
rule.length == 0
rule.equals(null)
You already assumed that your element at 0 index is not null , and calling equals() and matches() method on element at 0th index causing NullPointerException
Thrown when an application attempts to use null in a case where an
object is required. These include:
Calling the instance method of a null object.
Accessing or modifying the field of a null object.
Taking the length of null as if it were an array.
Accessing or modifying the slots of null as if it were an array.
Throwing null as if it were a Throwable value.
Instead try like this
if(rule[0] != null){
// Now you can call methods on your `0th` index element
}

If I have a method name stored in a 2D array as a String, is it possible for me use that String to call said method?

I am trying to write a program that will help me calculate conversions of certain cooking measurements. I'm sure there are easier ways to go about this, but this is what I've got so far:
public void sort(String[] s)
{
for (int i = 0; i < s.length; i++)
s[i] = s[i].toLowerCase();
try
{
if (s[0].equals("metric"))
{
for (int i = 0; i < metric.length; i++)
{
if (s[1].equals(metric[i]))
{
metric[i][1]();
}
}
} else if (s[0].equals("imperial"))
{
}
} catch (IllegalArgumentException e)
{
System.out.println(e);
System.out.print(errorMessage);
}
}
s is an array containing information about what the user is converting from, to, and how much. I have also made two 2D arrays containing in each 1st-dimension element the measurement, and the corresponding method name that goes with it. What I want to do is extract that method name from the 2d array, thus calling the method. For example, the line that says metric[i]1; should call what ever method name is stored at metric[i][1]. How would I go about this if at all possible? Also sorry if this question is confusing, and if you have input on how this could be program could be written more intuitively, I would appreciate it.
Yeah, if you know, and can access the class...
Here is an example of how to run a method by name (Let selectedClass be the class in which its located):
Method theMethod = selectedClass.getClass().getMethod("methodName", null);
theMethod.invoke(selectedClass, null);

Categories

Resources