I am trying to refector a 2D array project to include a search method to clean up the code in my main method. However, when I enter a valid name it can find the first row of data but will also print the else statement. If I enter a valid name for second row it will sometimes return it after printing the else statement.
I've tried rewriting the code, creating a return variable for the method, using a nested loop, modifying the return array value.
static Scanner scan = new Scanner(System.in);
public static void main(String[] args) {
System.out.println("==== Family Affair ====");
System.out.println("How many members will you add?");
int number = scan.nextInt(); scan.nextLine();//scan.nextLine() ad hoc scan fix
//2D Array number of rows by scan/number input
String[][] familyData = new String[number][2];
//for loop captures input column data for each row
//nested loop created duplicate output
for (int i = 0; i < familyData.length; i++) {
System.out.print("\tName: ");
familyData[i][0] = scan.nextLine();
System.out.print("\tState: ");
familyData[i][1] = scan.nextLine();
System.out.println(" ");
}
System.out.println(" ");//extra space
printData(familyData);//call printData() method
findData(familyData);//call findData() method
}
public static void printData(String[][] data) {
for (int i = 0; i < data.length; i++) {
System.out.print("\tName: " + data[i][0] + " ");
System.out.print("\tState: " + data[i][1] + " ");
System.out.println(" ");
}
}
public static String[] findData(String[][] data) {
System.out.println("SEARCH...");
System.out.println("First Name: ");
String name = scan.nextLine();
String[] resultData = new String[0];
for (int i = 0; i < data.length; i++) {
if (name.equals(data[i][0])) {
System.out.println("--- Search Results ---");
System.out.println("\tName: " + data[i][0]);
System.out.println("\tState: " + data[i][1]);
}else {
System.out.println("Nothing found. Try Again");
System.out.println("First Name: ");
name = scan.nextLine();
}
}
return resultData; //returned as String[] results = findData(param);
}
Let me suggest the use of List<>
import java.util.ArrayList;
import java.util.List;
private static List<String[]> findData(String[][] source, String search)
{
final List<String[]> data = new ArrayList<>();
for (String[] array : source)
{
if (search.equals(array[0]))
{
data.add(array);
}
}
return data;
}
And here is an example of use
public static void main(String args[])
{
String[][] familyData = new String[2][2];
familyData[0][0] = "Sulabha";
familyData[0][1] = "Married";
familyData[1][0] = "Bertram";
familyData[1][1] = "Single";
List<String[]> data = findData(familyData, "Sulabha");
if (data.size() == 0)
{
System.out.println("Nothing found.");
}
else
{
for (String[] item : data)
{
System.out.println("--- Search Results ---");
System.out.println("\tName: " + item[0]);
System.out.println("\tState: " + item[1]);
}
}
}
This question already has answers here:
Why does the default Object.toString() include the hashcode?
(3 answers)
Closed 8 months ago.
I was working on a problem for a club and tried to run it, here is the code:
package week23.UniversityProblem;
import java.util.ArrayList;
import java.util.Scanner;
public class UniversityProblem {
public static void main(String[] args) {
Lesson math101 = new Lesson();
math101.name = "Mathematics";
math101.credit = 4;
Lesson phys101 = new Lesson();
phys101.name = "Physics";
phys101.credit = 3;
Lesson cs102 = new Lesson();
cs102.name = "Computer Science";
cs102.credit = 3;
Lesson ictapp = new Lesson();
ictapp.name = "Ict applications";
ictapp.credit = 3;
Lesson rs101 = new Lesson();
rs101.name = "Romainian Studies";
rs101.credit = 3;
int o = 0;
Scanner scanner = new Scanner(System.in);
Scanner scanner2 = new Scanner(System.in);
while (o != 2){
System.out.println("What option do you want to use:");
System.out.println("1. Add & Print");
System.out.println("2. Exit");
o = scanner.nextInt();
if(o == 1){
Student s = new Student();
System.out.println("Name:");
s.name = scanner2.nextLine();
int c = 0;
int o2 = 0;
while(c < s.maxCredit){
System.out.println("What course would you like to take:");
System.out.println("1. " + math101.name);
System.out.println("2. " + phys101.name);
System.out.println("3. " + cs102.name);
System.out.println("4. " + ictapp.name);
System.out.println("5. " + rs101.name);
System.out.println("6. Exit");
o2 = scanner.nextInt();
if(o2 == 1){
s.arr2.add(math101);
c += math101.credit;
} else if (o2 == 2) {
s.arr2.add(phys101);
c += phys101.credit;
} else if (o2 == 3) {
s.arr2.add(cs102);
c += cs102.credit;
} else if (o2 == 4) {
s.arr2.add(ictapp);
c += ictapp.credit;
} else if (o2 == 5) {
s.arr2.add(rs101);
c += rs101.credit;
} else if (o2 == 6) {
break;
}
}
System.out.println(s.name + " ");
for (int i = 0; i < s.arr2.size(); i++) {
System.out.println(s.arr2.get(i));
}
}
}
}
}
And here is my lesson class and it's attributes:
package week23.UniversityProblem;
import java.util.ArrayList;
public class Lesson {
String name;
int credit;
}
And here is my Student class and it's attributes. Also, my arraylist is in the Student class. All of my lessons are stored in this arraylist. At the end I want to display student name and his/her lesson names with credits
package week23.UniversityProblem;
import java.util.ArrayList;
public class Student {
String name;
int maxCredit = 10;
ArrayList<Lesson> arr2 = new ArrayList<>();
}
After choosing my options from the menu i added, here is what it displays:
Tudor
week23.UniversityProblem.Lesson#77459877
week23.UniversityProblem.Lesson#5b2133b1
The Lesson class does not override the toString() method provided by the Object class (which all objects extend directly if they are not declared to extend some other object). As such, the JRE will use the toString() method of the Object class. The javadoc for that implementation states that this will be
getClass().getName() + '#' + Integer.toHexString(hashCode())
The result you get in your console is the hashcode value of an object. Since the object has no toString method to determine how it should be printed as a String. It instead prints the hashcode value which is the output you are receiving.
There are multiple ways to solve this issue. Here is one example: Add a toString method to your Lesson class:
public String toString(){//overriding the toString() method
return "Name: "+name+", Credit: "+credit;
}
Query by loan ID
// Method that allows the user to query by loan ID
public static void QuerybyloanID(List<Loan> data) {
try (Scanner entry = new Scanner(System.in)) {
System.out.print("Please, enter the loan ID: ");
String userentry = entry.next();
// For loop is used to locate the loan ID within the list of loans
for (int i = 0; i < data.size(); i++) {
String loanID = data.get(i).getLoanID();
if (loanID.equals(userentry)) {
boolean pass = true;
String loanPassword = data.get(i).getPasscode();
// Three possible character from the loan password
int one;
int two;
int three;
int [] randomCharacters = randomUniqueGenerator(3, loanPassword.length());
one = randomCharacters[0];
two = randomCharacters[1];
three = randomCharacters[2];
// Check to see if the random numbers are the same or different. -> Implement a Hash Map.
char entry_one = loanPassword.charAt(one);
char entry_two = loanPassword.charAt(two);
char entry_three = loanPassword.charAt(three);
String entry_one_modify = Character.toString(entry_one);
String entry_two_modify = Character.toString(entry_two);
String entry_three_modify = Character.toString(entry_three);
String [] entriesmain = {entry_one_modify, entry_two_modify, entry_three_modify};
try (Scanner entrytwo = new Scanner(System.in)) {
for (int k = 0; k < 3; k ++) {
System.out.print("Enter character " + randomCharacters[k] + " of the loan pass code: ");
String userentrytwo = entrytwo.next();
entrytwo.nextLine();
if (userentrytwo.equals(entriesmain[k])) {
continue;
} else {
pass = false;
continue;
}
}
}
// Check to see if pass is true or false then take the appropriate action
if (pass) {
System.out.println("Customer Name: " + data.get(i).getFirstName() + " " + data.get(i).getLastName());
System.out.println("Branch Code: " + data.get(i).getBrachCode());
System.out.println("Gender: " + data.get(i).getGender());
System.out.println("Date of Birth: " + data.get(i).getDOB());
System.out.println("Loan Amount: " + data.get(i).getLoanAmount());
System.out.println("Customer Phone Number: " + data.get(i).getPhoneNumber());
MainMenu.options();
} else {
System.out.println("Wrong Passcode !");
MainMenu.options();
}
}
I'm pretty new to coding so please bear with me, I am just experimenting with ways to shuffle an array for eventual use in shuffling a deck of cards in a card game I am creating in Java. I know that index 5 is out of bounds for length 5 but what is puzzling to me is that the error doesn't ALWAYS pop up. Sometimes I try to run my code and it works just fine, other times I get the error even if I haven't changed anything between times that I run it.
public class Card{
public static void shuffle(Object[] array) {
int noOfCards = array.length;
for (int i = 0; i < noOfCards; i++) {
int s = i + (int)(Math.random() * (noOfCards - 1));
Object temp = array[s]; //this is the first line it says has a problem
array[s] = array[i];
array[i] = temp;
}
}
public static void main(String[] args) {
String[] strOfCards = {"A","B","C","D","E"};
Card.shuffle(strOfCards); //this is the second line that has a problem
for(int i = 0; i < strOfCards.length; i++) {
System.out.println(strOfCards[i] + " ");
}
}
}
I have no idea how to change the flawed lines, any suggestions are welcome!
*** i have tried changing the number of letters in the string but then the error changes with it i.e. "Index 6 out of bounds for length 6"
Consider the lines:
for (int i = 0; i < noOfCards; i++) {
int s = i + (int)(Math.random() * (noOfCards - 1));
Object temp = array[s]; //this is the first line it says has a problem
i varies from 0 to noOfCards - 1
Your random number expression varies from 0 to noOfCards - 2
So s varies from 0 to (2 * noOfCards) - 3
Then array[s] will throw an exception whenever s >= noOfCards
It doesn't happen every time you run it because sometimes the random numbers all happen to be under noOfCards
If you want to swap with a random other card then you could try:
Random random = new Random();
int s = (i + random.nextInt(noOfCards - 1)) % noOfCards;
I realise you're using this as a learning opportunity, but in case you weren't aware, there is a Collections.shuffle method that can be used to shuffle collections such as ArrayList in one command.
Max index of array with length N is (N-1). Code should be like this:
public static void shuffle(Object[] array) {
int noOfCards = array.length;
Random random = new Random();
for (int i = 0; i < noOfCards; i++) {
int s = random.nextInt(noOfCards);
Object temp = array[s];
array[s] = array[i];
array[i] = temp;
}
}
Here is the line that causes the trouble:
int s = i + (int)(Math.random() * (noOfCards - 1));
Whenever the value s is >= 5, the array[s] will point to something out of bound.
For example i can be 3, if Math.random() returns something like 0.5, then 3 + (int)(0.5 * 4) is equal to 5, which is out of bound (0..4)
It doesn't happen all the times, because some times the Math.random() generates small enough number, so the evaluation of s is smaller than 5.
To ensure that the value of s always in the range (0..4), you should modulo the result to 5.
Here is how the line should be:
int s = (i + (int)(Math.random() * (noOfCards - 1))) % 5;
change this line
int s = i + (int)(Math.random() * (noOfCards - 1));
to this
int s = (int)(Math.random() * (noOfCards - 1));
just remove i variable from the above code
You need to remember that indices are zero-based in Java.
Note a couple of things:
- make things final if they're final
- use SecureRandom: it is more random than Random
- use the nextInt(n) method of SecureRandom to get an int in your range
- note the use of Streams to print out the result
import java.security.SecureRandom;
import java.util.stream.Stream;
public class Card {
public static void shuffle(final Object[] array) {
final SecureRandom random = new SecureRandom();
final int noOfCards = array.length;
for (int i = 0; i < noOfCards; i++) {
final int s = random.nextInt(noOfCards);
final Object temp = array[s];
array[s] = array[i];
array[i] = temp;
}
}
public static void main(final String[] args) throws Exception {
final String[] strOfCards = {"A","B","C","D","E"};
Card.shuffle(strOfCards);
Stream.of(strOfCards).forEach(System.out::println);
}
}
If you fancy using a List it's a bit more compact:
import java.security.SecureRandom;
import java.util.*;
import java.util.stream.IntStream;
public class Card {
public static void main(final String[] args) throws Exception {
final SecureRandom random = new SecureRandom();
final List<String> cards = Arrays.asList("A", "B", "C", "D", "E");
IntStream.range(0, cards.size()).forEach(i ->
Collections.swap(cards, i, random.nextInt(cards.size()))
);
cards.forEach(System.out::println);
}
}
M getting the same issue with this code and still no idea how to solve it
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.List;
import java.util.ArrayList;
import javax.swing.JOptionPane;
public class Main
{
public static void main (String[] args)
{
while (true)
{
String number = JOptionPane.showInputDialog("Please Enter \n"
+ "1 for 'Add new Employee'"
+ "\n 2 for 'Search in employee'"
+ "\n 3 for 'Exit'");
int convertnumber = Integer.parseInt(number);
if (convertnumber == 1)
{
addEmployee();
}
else if (convertnumber == 2)
{
String eId = JOptionPane.showInputDialog("Enter ID to search");
searchEmplye(eId);
}
else if (convertnumber == 3)
{
JOptionPane.showMessageDialog(null, "Developed By: BC180401942 SHEHZAD ADEEL");
System.exit(0);
}
else
{
JOptionPane.showMessageDialog(null, "Invalid input");
}
}
}
public static void searchEmplye(String eId)
{
try
{
String tokens[] = null;
String id, name, dob, qual, expe, pays;
FileReader fr = new FileReader("empData.txt");
BufferedReader br = new BufferedReader(fr);
String line = br.readLine();
if (line == null)
{
JOptionPane.showMessageDialog(null, "Employee Not found");
}
while (line != null)
{
tokens = line.split (",");
id = tokens[0];
name = tokens[1];
dob = tokens[2];
qual = tokens[3];
expe = tokens[4];
pays = tokens[5];
Employee emp = new Employee (id, name, dob, qual, expe, pays);
ArrayList list = new ArrayList();
list.add(emp);
line = br.readLine();
/*
for (int i = 0; i < list.size(); i++)
{
Employee p = (Employee) list.get(i);
if (eId.equals(p.getEmpId()))
{
JOptionPane.showMessageDialog(null, "Employee: \n"
+ "Employee ID: " + p.getEmpId()
+ " \n Employee Name: " +p.getEmpName()
+ " \n Employee DOB: " + p.getEmpDoB()
+ " \n Qualification: " + p.getEmpQualf()
+ " \n Experience: " + p.getEmpExp()
+ " \n Pay Scal: " + p.getEmpPSacle()
);
}
*/
for (int i = 0; i < list.size(); i++)
{
Employee p = (Employee) list.get(i);
if (eId.equals(p.getEmpId()))
{
JOptionPane.showMessageDialog( null, "Employee: \n" +
"EmpId: " + p.getEmpId() + "\n" +
"Name: " + p.getEmpName() + "\n" +
"DoB: " + p.getEmpDoB() + "\n" +
"Qualification: " + p.getEmpQualf() + "\n" +
"Experience: " + p.getEmpExp() + "\n" +
"PayScale: " + p.getEmpPScale() );
}
else
{
JOptionPane.showMessageDialog(null, "Employee Not found");
}
}
}
br.close();
fr.close();
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
public static void addEmployee()
{
try
{
ArrayList list = new ArrayList();
String id = JOptionPane.showInputDialog("Enter Employee ID: ");
String name = JOptionPane.showInputDialog("Enter name: ");
String dob = JOptionPane.showInputDialog("Enter DoB (year): ");
String qual = JOptionPane.showInputDialog("Enter Qualification: ");
String exp = JOptionPane.showInputDialog("Enter Employee experience (in months): ");
String pays = JOptionPane.showInputDialog("Enter Employee Pay Scale (in number): ");
Employee emp = new Employee (id, name, dob, qual, exp, pays);
list.add(emp);
/*
ArrayList list = new ArrayList();
String id = JOptionPane.showInputDialog("Enter ID ");
String name = JOptionPane.showInputDialog("Enter Name ");
String dob = JOptionPane.showInputDialog("Enter DOB ");
String qualification = JOptionPane.showInputDialog("Enter qualification ");
String experience = JOptionPane.showInputDialog("Enter Employee Experience");
String paScale = JOptionPane.showInputDialog("Enter Employee pay scale ");
Employee emp = new Employee(id, name, qualification, experience, paScale);
list.add(emp);
*/
String line;
FileWriter fw = new FileWriter("empData.txt");
PrintWriter pw = new PrintWriter(fw);
for (int i = 0; i < list.size(); i++)
{
emp = (Employee) list.get(i);
//line = emp.getEmpId() + "," + emp.getEmpName() + "," + emp.getEmpDoB() + "," + emp.getEmpQualf() + "," + emp.getEmpExp() + "," + emp.getEmpPSacle();
line = emp.getEmpId() + "," +
emp.getEmpName() + "," +
emp.getEmpDoB() + "," +
emp.getEmpQualf() + "," +
emp.getEmpPScale();
pw.println(line);
}
pw.flush();
pw.close();
fw.close();
}
catch (IOException ioEx)
{
System.out.println(ioEx);
}
}
}
I'm currently working on a version of hangman through java. I've recently been stumped by a problem that I can't seem to solve.
I have an array easyDifficulty and a String hiddenWord. I want to make it so that every time the game starts, my method randomWord() will choose a random word from array easyDifficulty to start the program. Many of my methods use hiddenWord so I pasted all of my code below incase you need to check that. Otherwise, the main parts that I feel like that are causing problems are in the area where I declare my field variables, my randomWord method, and the main method.
import java.util.Arrays;
import java.util.*;
import java.util.Scanner;
public class HangmanGame {
static String[] easyDifficulty = new String[]{"orange", "jacket","shirt"
,"rocket","airplane","circle","balloon","swing","truck","caterpillar"};
static Random rand = new Random();
static String hiddenWord = new String("");
static char[] hiddenWordToChar = hiddenWord.toCharArray();
static int triesLeft = 6;
static boolean done = false;
static int length = hiddenWord.length();
static Scanner input = new Scanner(System.in);
final static int maxLength = 30;
static char[] repeatChecker = new char[30]; //this is to help prevent the user from putting the same char multiple times
static char[] fillWord = new char[length];
static int var;
static int var2;
static char underscore = '_';
static int chooseDifficultyInt;
public static String randomWord(int n) {
int randomNum = rand.nextInt(9);
int difficultyInt = n;
if (difficultyInt == 1){
//System.out.println(easyDifficulty[randomNum]);
return easyDifficulty[randomNum];
}
return null;
}
public static boolean contains(char[] arr, char i) {
for (char n : arr) {
if (i == n) {
return true;
}
}
return false;
}
public static boolean multiLetter(char[] arr, char i){
int multiple = 0;
for (char n : arr){
if (i == n){
multiple++;
//continue;
}
}
System.out.println(multiple);
if (multiple > 1){
return true;
}
else {
return false;
}
}
public static void createSpaces(int n){
for (int i = 0; i <= n-1; i++){
fillWord[i] = underscore;
}
System.out.println(fillWord);
}
public static void tryAgain(){
System.out.println("Would you like to try again? Enter Y/N to go again or quit!");
char goAgain = input.next().charAt(0);
goAgain = Character.toLowerCase(goAgain);
if (goAgain == 'y') {
triesLeft = 6;
repeatChecker = new char[20];
main(null);
}
else if (goAgain == 'n') {
System.out.println("Bye!");
System.exit(0);
}
else {
System.out.println("Invalid input");
tryAgain();
}
}
public static void arrayLetters(){
System.out.println("This is a " + length + " letter word. Please enter a letter to guess: ");
char charInput = input.next().charAt(0);
char[] letters = new char[20];
//This code only runs if the user inputs a letter that repeats
//throughout hiddenWord
if (multiLetter(hiddenWordToChar, charInput)){
for (int n = 0; n < length; n++){
char multiWordLetter = hiddenWord.charAt(n);
letters[n] = multiWordLetter;
if (letters[n] == charInput){
fillWord[n] = charInput;
}
if (contains(repeatChecker, charInput)){
System.out.println("You already did that word, try again!");
arrayLetters();
}
if (Arrays.equals(fillWord, hiddenWordToChar)){
System.out.println("Congratulations, you win! The word was '" + hiddenWord + "'!");
System.out.println("You completed the challenge in " + triesLeft + " tries! \n\n");
tryAgain();
}
}
System.out.println(fillWord);
System.out.println("Nice! There is a(n) " + charInput + " in this word!");
System.out.println("You have " + triesLeft + " tries left!\n");
arrayLetters();
}
//This block of code runs when the user input a letter that only occurs once
//in hiddenWord
for (int i = 0; i < length; i++){
char wordLetter = hiddenWord.charAt(i);
letters[i] = wordLetter;
if (contains(letters, charInput)){
/*
if (multiLetter(letters, charInput)){
System.out.println("aylmao");
}
*/
//System.out.println(multiLetter(hiddenWordArray, charInput));
if (contains(repeatChecker, charInput)){
System.out.println("You already did that word, try again!");
arrayLetters();
}
repeatChecker[var] = charInput;
var++;
fillWord[i] = charInput;
if (Arrays.equals(fillWord, hiddenWordToChar)){
System.out.println("Congratulations, you win! The word was '" + hiddenWord + "'!");
System.out.println("You completed the challenge in " + triesLeft + " tries! \n\n");
tryAgain();
}
System.out.println(fillWord);
System.out.println("Nice! There is a(n) " + charInput + " in this word!");
System.out.println("You have " + triesLeft + " tries left!\n");
arrayLetters();
}
if (i == length-1){
System.out.println("There is no " + charInput + " in this word!");
triesLeft--;
System.out.println("You have " + triesLeft + " tries left!\n");
if (triesLeft <= 0){
System.out.println("You failed!\n\n");
tryAgain();
}
arrayLetters();
}
}
}
public static void main(String[] args) {
System.out.println("Welcome to my hangman game!");
System.out.println("Please input your prefered difficulty level.");
System.out.println("1. Easy");
System.out.println("2. Medium");
System.out.println("3. Hard");
chooseDifficultyInt = input.nextInt();
randomWord(chooseDifficultyInt);
hiddenWord = randomWord(chooseDifficultyInt);
createSpaces(length);
arrayLetters();
}
}
I'm an intermediate in java programming so I've learned that Strings are immutable. Thus I've considered that the reason why hiddenWord won't be set equal to randomWord(chooseDifficultyInt); is because of that?
I'm an intermediate in java programming so I've learned that Strings are immutable
This often causes confusion among new programmers. This is correct, Strings are immutable. However the variable that points to that String can be re-assigned (assuming it isn't final).
You can modify your hidden word as many times as you like:
HangmanGame.hiddenWord = "MyNewWord";
HangmanGame.hiddenWord = "AnotherWord";
HangmanGame.hiddenWord = "ThisWorks";
You might be wondering how the hiddenWord is changing if Strings are immutable.
Your variable isn't actually changing. Every time you re-assign it, a new String is being created. This means that the Strings themselves are never modified.
So yes, you can call
HangmanGame.hiddenWord = HangmanGame.randomWord(n);
and it will work perfectly.
Your initialization of hiddenWord as new String(""); is useless. You could remove it safely.
When you do that:
hiddenWord = randomWord(chooseDifficultyInt);
you set hiddenWord to the reference of a random string of your predefined list, not allocating anything, just reusing an existing string reference.