This question already has answers here:
Compare objects in LinkedList.contains()
(6 answers)
Closed 9 years ago.
I'm trying to check if an object exists within a linked list, and perform an action depending on if it exists or not, however, java is treating all the objects as different no matter what I do. The main code is provided below, and I'm pretty sure the error in the logic is in this code. The article and customer classes are very standard. The flag variable, which is supposed to be true if the list contains the article with the title, is always false. Any help would be much appreciated.
import java.util.*;
import java.io.*;
public class Proj1 {
public static void main(String[] args) throws FileNotFoundException {
LinkedList<Article> Articles = new LinkedList<Article>();
LinkedList<Customer> Customers = new LinkedList<Customer>();
ListIterator<Customer> it = Customers.listIterator();
int id = 0;
String command = "";
if (args.length == 0 || args[0] == null) {
System.out.println("Please give a valid command file");
} else {
try {
Scanner reader = new Scanner(new FileInputStream(args[0]));
while (reader.hasNext()) {
String arg = reader.nextLine();
arg.split(" ");
String[] commands = arg.split("\\s+");
if (isInt(commands[0])) {
id = Integer.parseInt(commands[0]);
command = commands[1];
Customer temp = new Customer(id);
if (Customers.size() == 0) {
Customers.add(temp);
} else {
boolean flag = false;
for (int i = 0; i < Customers.size(); i++) {
if (id == Customers.get(i).getId()) {
flag = true;
}
}
if (flag == false) {
Customers.add(temp);
}
}
} else {
command = commands[0];
}
// System.out.println(id+" "+command);
if (command.equalsIgnoreCase("borrow")) {
String title = "";
int x = commands.length;
boolean flag = false;
for (int j = 2; j < x; j++) {
title += commands[j] + " ";
}
Article Article = new Article(title);
System.out.println(Articles.size());
if (Articles.size() == 0) {
Articles.add(Article);
} else {
for (int i = 0; i < Articles.size(); i++) {
if (Article.getTitle() == Articles.get(i).getTitle()) {
flag = true;
}
}
if (flag == false) {
Articles.add(Article);
}
}
System.out.println(flag);
for (int i = 0; i < Customers.size(); i++) {
if (Customers.get(i).CustomerList().contains(title) && flag == true) {
Article.addToQ(Customers.get(i));
} else {
Customers.get(i).CustomerBorrow(Article);
}
}
// System.out.println(title);
} else if (command.equalsIgnoreCase("return")) {
String title = "";
int x = commands.length;
for (int j = 2; j < x; j++) {
title += commands[j] + " ";
}
Article Article = new Article(title);
if (Articles.size() == 0) {
Articles.add(Article);
} else {
boolean flag = false;
for (int i = 0; i < Articles.size(); i++) {
if (title == Articles.get(i).getTitle()) {
flag = true;
}
}
if (flag == false) {
Articles.add(Article);
}
}
for (int i = 0; i < Customers.size(); i++) {
if (id == Customers.get(i).getId()) {
Customers.get(i).CustomerReturn(Article);
}
}
// System.out.println(title);
} else if (command.equalsIgnoreCase("list")) {
for (int i = 0; i < Customers.size(); i++) {
if (id == Customers.get(i).getId()) {
System.out.println("Customer " + id
+ " currently has: "
+ Customers.get(i).CustomerList());
}
}
} else if (command.equalsIgnoreCase("whohas")) {
String title = "";
int x = commands.length;
for (int i = 1; i < x; i++) {
title += commands[i] + " ";
}
boolean flag = false;
int tempId = 0;
for (int i = 0; i < Customers.size(); i++) {
tempId = Customers.get(i).getId();
if (Customers.get(i).CustomerList().contains(title)) {
flag = true;
tempId = Customers.get(i).getId();
}
}
if (flag = true) {
System.out.println(tempId + " currently has "
+ title);
} else {
System.out
.println("Currently no one has checked out "
+ title);
}
// System.out.println(title);
} else if (command.equalsIgnoreCase("waitlist")) {
String title = "";
int x = commands.length;
for (int i = 1; i < x; i++) {
title += commands[i] + " ";
}
for (int i = 0; i < Customers.size(); i++) {
if (Customers.get(i).CustomerList().contains(title)) {
Articles.get(i).printQ();
}
}
// System.out.println(title);
} else if (command.equalsIgnoreCase("listCustomers")) {
System.out.println("Customers include: ");
for (int i = 0; i < Customers.size(); i++) {
System.out.println(Customers.get(i).getId());
}
} else {
System.out.println("Command not recognized");
}
}
reader.close();
}
catch (Exception e) {
System.out.println("command not formatted correctly");
}
}
}
public static boolean isInt(String string) {
try {
Integer.parseInt(string);
} catch (NumberFormatException nfe) {
return false;
}
return true;
}
}
commands such as
29 borrow "new york times"
29 borrow "new york times"
allow duplicates, and I'm trying to avoid this. Thanks.
Could it be that
if (Article.getTitle() == Articles.get(i).getTitle()) {
intends to compare strings? That would explain why your flag always comes back false. To compare strings in Java you should use equals (or equalsIgnoreCase for case-insensitive comparison)
if (Article.getTitle().equals(Articles.get(i).getTitle()) {
More background information here
I'm only guessing, but I'd bet that you either didn't override equals and hashCode in your Customer and Article classes or you didn't do it properly.
Joshua Bloch shows you how in Chapter 3 of "Effective Java".
I'd also wonder why you didn't choose the Set data structure if duplicates weren't allowed.
Related
Prompt: Write a program that reads five cards from the user, then analyzes the cards and prints out the category of hand that they represent.
Poker hands are categorized according to the following labels: Straight flush, four of a kind, full house, flush, straight, three of a kind, two pairs, pair, high card.
I currently have my program set as follows, first prompting the user for 5 cards, 2-9, then sorting the cards in ascending order. I set up my program to prompt the user and then go through several if else statements calling methods. I am having issues though where its not identifying three or four of a kind.
Example, if I enter 1, 3, 2, 1, 1, it identifies it as TWO PAIRS instead of Three of a Kind.
Same for entering 1, 1,1, 1, 4, it identifies as three of kind instead of 4.
Any suggestions to my code?
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
final int HAND_SIZE = 5;
int[] hand = new int[HAND_SIZE];
getHand(hand); //Prompt user for hand
sortHand(hand);//Sort hand in ascending order
if(containsFullHouse(hand))
{
System.out.print("FULL HOUSE!");
}
else if(containsStraight(hand))
{
System.out.print("STRAIGHT!");
}
else if(containsFourOfAKind(hand))
{
System.out.print("FOUR OF A KIND!");
}
else if(containsThreeOfAKind(hand))
{
System.out.println("THREE OF A KIND!");
}
else if(containsTwoPair(hand))
{
System.out.println("TWO PAIRS!");
}
else if(containsPair(hand))
{
System.out.println("PAIR!");
}
else
System.out.println("High Card!");
}
public static void getHand(int[] hand)
{
Scanner input = new Scanner(System.in);
System.out.println("Enter five numeric cards, 2-9, no face cards please");
for(int index = 0; index < hand.length; index++)
{
System.out.print("Card " + (index + 1) + ": ");
hand[index] = input.nextInt();
}
}
public static void sortHand(int[] hand)
{
int startScan, index, minIndex, minValue;
for(startScan = 0; startScan < (hand.length-1); startScan++)
{
minIndex = startScan;
minValue = hand[startScan];
for(index = startScan + 1; index <hand.length; index++)
{
if(hand[index] < minValue)
{
minValue = hand[index];
minIndex = index;
}
}
hand[minIndex] = hand[startScan];
hand[startScan] = minValue;
}
}
public static boolean containsPair(int hand[])
{
boolean pairFound = false;
int pairCount = 0;
int startCheck = hand[0];
for(int index = 1; index < hand.length; index++)
{
if((hand[index] - startCheck) == 0)
{
pairCount++;
}
startCheck = hand[index];
}
if (pairCount == 1)
{
pairFound = true;
}
else if(pairCount !=1)
{
pairFound = false;
}
return pairFound;
}
public static boolean containsTwoPair(int hand[])
{
boolean twoPairFound = false;
int twoPairCount = 0;
int startCheck = hand[0];
for(int index = 1; index < hand.length; index++)
{
if((hand[index] - startCheck) == 0)
{
twoPairCount++;
}
startCheck = hand[index];
}
if (twoPairCount == 2)
{
twoPairFound = true;
}
else if(twoPairCount != 2)
{
twoPairFound = false;
}
return twoPairFound;
}
public static boolean containsThreeOfAKind(int hand[])
{
boolean threeFound = false;
int threeKind = 0;
int startCheck = hand[0];
for(int index = 1; index < hand.length; index++)
{
if((hand[index] - startCheck) == 0)
{
threeKind++;
}
startCheck = hand[index];
}
if(threeKind == 3)
{
threeFound = true;
}
else if(threeKind !=3)
{
threeFound = false;
}
return threeFound;
}
public static boolean containsStraight(int hand[])
{
boolean straightFound = false;
int straight = 0;
int startCheck = hand[0];
for(int index = 1; index < hand.length; index++)
{
if((hand[index] - startCheck) == 1)
{
straight++;
}
startCheck = hand[index];
}
if(straight == 4)
{
straightFound = true;
}
return straightFound;
}
public static boolean containsFullHouse(int hand[])
{
boolean fullHouseFound = false;
int pairCheck = 0;
int startPairCheck = hand[0];
for(int index = 1; index < hand.length; index++)
{
if((hand[index] - startPairCheck) == 0)
{
pairCheck++;
}
startPairCheck = hand[index];
}
int threeOfKindCheck = 0;
int startThreeKindCheck = hand[0];
for(int index = 1; index < hand.length; index++)
{
if((hand[index] - startThreeKindCheck) == 0)
{
threeOfKindCheck++;
}
startThreeKindCheck = hand[index];
}
if(pairCheck == 1 && startThreeKindCheck == 3)
{
fullHouseFound = true;
}
return fullHouseFound;
}
public static boolean containsFourOfAKind(int hand[])
{
boolean fourFound = false;
int fourKind = 0;
int startCheck = hand[0];
for(int index = 1; index < hand.length; index++)
{
if((hand[index] - startCheck) == 0)
{
fourKind++;
}
startCheck = hand[index];
}
if(fourKind == 1)
{
fourFound = true;
}
else if(fourKind !=4)
{
fourFound = false;
}
return fourFound;
}
}
Some hints.
Start with the highest hand. This eliminates lots of logic.
I.e if you check for pairs first, than you also have to check to make sure that your pair is the only pair, and not three of a kind.
But if you already ruled all of those out your code would be check card 1and2 23 34 and 45.
I am suppose to use Boolean to check if the string is palindrome. I'm getting an error, not sure what I am doing wrong. My program already has 3 strings previously imputed by a user. Thank you, I am also using java
public boolean isPalindrome(String word1, String word2, String word3){
int word1Length = word1.length();
int word2Length = word2.length();
int word3Length = word3.length();
for (int i = 0; i < word1Length / 2; i++)
{
if (word1.charAt(i) != word1.charAt(word1Length – 1 – i))
{
return false;
}
}
return isPalindrome(word1);
}
for (int i = 0; i < word2Length / 2; i++)
{
if (word2.charAt(i) != word2.charAt(word2Length – 1 – i))
{
return false;
}
}
return isPalindrome(word2);
}
for (int i = 0; i < word3Length / 2; i++)
{
if (word3.charAt(i) != word3.charAt(word3Length – 1 – i))
{
return false;
}
}
return isPalindrome(word3);
}
// my output should be this
if (isPalindrome(word1)) {
System.out.println(word1 + " is a palindrome!");
}
if (isPalindrome(word2)) {
System.out.println(word2 + " is a palindrome!");
}
if (isPalindrome(word3)) {
System.out.println(word3 + " is a palindrome!");
}
You could do a method for it like this:
First you build a new String and than you check if it is equal.
private static boolean test(String word) {
String newWord = new String();
//first build a new String reversed from original
for (int i = word.length() -1; i >= 0; i--) {
newWord += word.charAt(i);
}
//check if it is equal and return
if(word.equals(newWord))
return true;
return false;
}
//You can call it several times
test("malam"); //sure it's true
test("hello"); //sure it's false
test("bob"); //sure its true
I need help with this program because it is not compiling correctly.
The program is supposed to do this:
java PostfixToInfix
1 2 3 + *
1*(2+3)
I am getting these errors when compiling:
PostfixToInfix.java:64: error: bad operand types for binary operator '-'
s.push(o2 - o1);
^
first type: String
second type: String
PostfixToInfix.java:68: error: bad operand types for binary operator '*'
s.push(o1 * o2);
^
first type: String
second type: String
2 errors
How many I supposed to code this so that it works properly? I am unsure what is wrong with my code that it is not allowing it do the functions properly.
This is my code:
import java.util.Scanner;
import java.util.Stack;
public class PostfixToInfix
{
public static void main(String[] args)
{
String[] input = readExpr();
if(checkSyntax(input) == true)
{
int k = 0;
Stack<String> s = new Stack<>();
for(int i = 0; i < input.length; ++i)
{
if(isOperator(input[i]))
{
String o1;
String o2;
if(!(s.empty()))
{
o1 = s.pop();
}
else
{
for(int j = 0; j < i; ++j)
{
k += input[j].length() + 1;
}
System.out.println("Too few operands for " + input[i]);
writeExpr(input);
for(int l = 0; l < k; ++l)
{
System.out.print(" ");
}
System.out.println("^");
return;
}
if(!(s.empty()))
{
o2 = s.pop();
}
else
{
for(int j = 0; j < i; ++j)
{
k += input[j].length() + 1;
}
System.out.println("Too few operands for " + input[i]);
writeExpr(input);
for(int l = 0; l < k; ++l)
{
System.out.print(" ");
}
System.out.println("^");
return;
}
if(input[i].equals("+"))
{
s.push(o1 + o2);
}
else if(input[i].equals("-"))
{
s.push(o2 - o1);
}
else
{
s.push(o1 * o2);
}
}
else
{
s.push(input[i]);
}
}
String Result = s.pop();
if(!(s.empty()))
{
System.out.println("Too few operators to produce a single result");
}
else
{
System.out.println(Result);
}
}
} // end main
static String[] readExpr()
{
Scanner stdin = new Scanner(System.in);
String s = stdin.nextLine();
String[] sA = s.split(" ");
return sA;
}
static void writeExpr(String[] expr)
{
for(int i = 0; i < expr.length; ++i)
{
System.out.print(expr[i] + " ");
}
System.out.println();
}
static boolean isOperator(String s)
{
if(s.equals("+") || s.equals("-") || s.equals("*"))
{
return true;
}
return false;
}
static boolean checkSyntax(String[] expr)
{
int k = 0;
for(int i = 0; i < expr.length; ++i)
{
if(!(isOperator(expr[i])))
{
try
{
Double.parseDouble(expr[i]);
}
catch (Exception e)
{
for(int j = 0; j < i; ++j)
{
k += expr[j].length() + 1;
}
writeExpr(expr);
for(int l = 0; l < k; ++l)
{
System.out.print(" ");
}
System.out.println("^");
System.out.println("Not a number or valid operator");
return false;
}
}
}
return true;
}
} // end Postfix2
class StringStack
{
int top;
String[] pancake;
StringStack() //constructor for a new empty stack
{
top = 0;
pancake = new String[1000];
} // end DoubleStack
boolean empty() //whether the stack is empty
{
return top == 0;
} // end empty
String pop() //remove and return the top element; throw an error if empty
{
if(empty())
{
throw new Error("Error");
}
top -= 1;
return pancake[top];
} // end pop
void push(String x) //add x to the top of the stack
{
if(top < 1000)
{
pancake[top] = x;
top += 1;
}
else{
throw new Error("Error");
}
} // end push
} // end StringStack
Change you code like this.
if(input[i].equals("+"))
{
s.push(o1 + "+" + o2);
}
else if(input[i].equals("-"))
{
s.push(o2 + "-" + o1);
}
else
{
s.push(o1 + "*" + o2);
}
But the result for "1 2 3 + *" is "3+2*1".
It is another problem.
In my app I'm writing/reading an arrayList of objects that contain objects within them as well. (A list of BingoPages that contain BingoCells, both of which implement Serializable). The log works fine when printing values inside one of the BingoPages objects in the list, but when I call a method that deals with the inner BingoCells I get a null pointer exception. Any help greatly appreciated, been trying to get this save/load to work for too long!
My saveAll() method to save the data contains the following code:
String fileName = "bingoPages";
FileOutputStream outputStream;
try
{
outputStream = openFileOutput(fileName, Context.MODE_PRIVATE);
ObjectOutputStream oos = new ObjectOutputStream(outputStream);
oos.writeObject(allSheets);
oos.flush();
oos.close();
}
And my readAll() to load the data contains the following:
try
{
FileInputStream in = openFileInput("bingoPages");
ObjectInputStream ois = new ObjectInputStream(in);
allSheets = (ArrayList<BingoPage>)ois.readObject();
ois.close();
}
catch(Exception e)
{
allSheets = new ArrayList<BingoPage>();
}
Edit: Adding the code for the classes I am saving.
The simple BingoCell is as follows:
public class BingoCell implements Serializable{
public int num;
public int called;
public BingoCell(int id)
{
num = id;
called = 0;
}
}
And the BingoPage class:
public class BingoPage implements Serializable{
public int pageID;
public BingoCell[][] table;
public int index;
public String winnerLocation;
public BingoPage(int id)
{
table = new BingoCell[5][5];
pageID = id;
winnerLocation = null;
//the free space
table[2][2] = new BingoCell(999);
table[2][2].called = 1;
}
public void insertNum(int num, int column, int row)
{
table[row][column] = new BingoCell(num);
}
public String stringMe()
{
StringBuilder test = new StringBuilder();
for(int i = 0; i < 5; i++)
{
for(int j = 0; j < 5; j++)
{
test.append(table[i][j].num);
test.append(" | ");
}
test.append("\n\r");
}
return test.toString();
}
public void markNum(int markNum, int idx)
{
index = idx;
for(int i = 0; i < 5; i++)
{
for(int j = 0; j < 5; j++)
{
if(table[i][j].num == markNum)
{
table[i][j].called = 1;
checkForBingo();
}
}
}
}
private void checkForBingo()
{
testRows();
testColumns();
testDiagonals();
}
private void testRows()
{
int hasBingo = 1;
for(int i = 0; i < 5; i++)
{
hasBingo = 1;
for(int j = 0; j < 5; j++)
{
if(table[i][j].called == 0)
{
hasBingo = 0;
break; //Skip to the next column
}
}
if(hasBingo == 1)
{
//Alert that bingo on row i+1 if page pageID
alertWinner("Column " + (i+1));
}
}
}
private void testColumns()
{
int hasBingo = 1;
for(int i = 0; i < 5; i++)
{
hasBingo = 1;
for(int j = 0; j < 5; j++)
{
if(table[j][i].called == 0)
{
hasBingo = 0;
break; //row
}
}
if(hasBingo == 1)
{
//Alert that bingo on row i+1 if page pageID
alertWinner("Row " + (i+1));
}
}
}
private void testDiagonals()
{
if(table[0][0].called == 1 && table[1][1].called == 1 && table[2][2].called == 1
&& table[3][3].called == 1 && table[4][4].called == 1)
{
//Top left->bottom right bingo!
alertWinner("Top left->bottom right diagonal");
}
else if(table[0][4].called == 1 && table[1][3].called == 1 && table[2][2].called == 1
&& table[3][1].called == 1 && table[4][0].called == 1)
{
//Top right->bottom left bingo!
alertWinner("Top right->bottom left diagonal");
}
}
private void alertWinner(String location)
{
winnerLocation = new String(pageID + " at " + index + " sheets from bottom; location: " + location);
}
public void clear()
{
for(int i = 0; i < 5; i++)
{
for(int j = 0; j < 5; j++)
{
table[i][j].called = 0;
}
}
winnerLocation = null;
}
catch(Exception e)
{
allSheets = new ArrayList<BingoPage>();
}
The problem is surely here. Handling an exception by ignoring it and creating a dummy object instead is no way to debug your code, or even to write it in the first place. You should print the stack trace at this point and fix whatever the problem is.
Java won't stop reading from input.
I understand that maybe this while loop might have something to do with it:
while(input.hasMoreTokens());
{
array1[counter] = input.nextToken();
counter++;
}
But I don't see why the loop should be a problem because I am already calling .nextToken() which should advance the token.
Here's the full source code:
import java.io.*;
import java.util.*;
class HelloWorld
{
static String ReadLn (int maxLg) // utility function to read from stdin
{
byte lin[] = new byte [maxLg];
int lg = 0, car = -1;
String line = "";
try
{
while (lg < maxLg)
{
car = System.in.read();
if ((car < 0) || (car == '\n')) break;
lin [lg++] += car;
}
}
catch (IOException e)
{
return (null);
}
if ((car < 0) && (lg == 0)) return (null); // eof
return (new String (lin, 0, lg));
}
public static void main (String args[]) // entry point from OS
{
HelloWorld myWork = new HelloWorld(); // create a dinamic instance
myWork.Begin(); // the true entry point
}
void Begin()
{
String idata;
StringTokenizer input;
while ((idata = HelloWorld.ReadLn (255)) != null)
{
input = new StringTokenizer (idata);
String[] array1 = {};
int counter = 0;
while(input.hasMoreTokens());
{
array1[counter] = input.nextToken();
counter++;
}
int[] array2 = {};
for(int a = 0; a < array1.length; a++)
{
array2[a] = Integer.parseInt(array1[a]);
}
int[] array3 = {};
for(int b = 0; b < array2.length; b++)
{
if ( array2[b] != 42)
{
array3[b] = array2[b];
}
else
{
break;
}
}
String string = "";
for( int c = 0; c < array3.length; c++)
{
if( c < array3.length - 1)
{
string += array3[c] + "\n";
}
else
{
string += array3[c];
}
}
System.out.println(string);
}
}
}
You have a stray semicolon at the end of the while:
while(input.hasMoreTokens());
^ REMOVE THIS