I read Bert Bates and Katie Sierra's book Java and have a problem.
The Task: to make the game "Battleship" with 3 classes via using ArrayList.
Error: the method setLocationCells(ArrayList < String >) in the type
SimpleDotCom is not applicable for the arguments (int[])
I understand that ArrayList only will hold objects and never primatives. So handing over the list of locations (which are int's) to the ArrayList won't work because they are primatives. But how can I fix it?
Code:
public class SimpleDotComTestDrive {
public static void main(String[] args) {
int numOfGuesses = 0;
GameHelper helper = new GameHelper();
SimpleDotCom theDotCom = new SimpleDotCom();
int randomNum = (int) (Math.random() * 5);
int[] locations = {randomNum, randomNum+1, randomNum+2};
theDotCom.setLocationCells(locations);
boolean isAlive = true;
while(isAlive) {
String guess = helper.getUserInput("Enter the number");
String result = theDotCom.checkYourself(guess);
numOfGuesses++;
if (result.equals("Kill")) {
isAlive = false;
System.out.println("You took " + numOfGuesses + " guesses");
}
}
}
}
public class SimpleDotCom {
private ArrayList<String> locationCells;
public void setLocationCells(ArrayList<String> loc) {
locationCells = loc;
}
public String checkYourself(String stringGuess) {
String result = "Miss";
int index = locationCells.indexOf(stringGuess);
if (index >= 0) {
locationCells.remove(index);
if(locationCells.isEmpty()) {
result = "Kill";
} else {
result = "Hit";
}
}
return result;
}
}
public class GameHelper {
public String getUserInput(String prompt) {
String inputLine = null;
System.out.print(prompt + " ");
try {
BufferedReader is = new BufferedReader(new InputStreamReader(System.in));
inputLine = is.readLine();
if (inputLine.length() == 0)
return null;
} catch (IOException e) {
System.out.println("IOException:" + e);
}
return inputLine;
}
}
convert ArrayList to int[] in Java
Reason for Basic Solution
Here's a simple example of converting ArrayList<String> to int[] in Java. I think it's better to give you an example not specific to your question, so you can observe the concept and learn.
Step by Step
If we have an ArrayList<String> defined below
List<String> numbersInAList = Arrays.asList("1", "2", "-3");
Then the easiest solution for a beginner would be to loop through each list item and add to a new array. This is because the elements of the list are type String, but you need type int.
We start by creating a new array of the same size as the List
int[] numbers = new int[numbersInAList.size()];
We then iterate through the list
for (int ndx = 0; ndx < numbersInAList.size(); ndx++) {
Then inside the loop we start by casting the String to int
int num = Integer.parseInt(numbersInAList.get(ndx));
But there's a problem. We don't always know the String will contain a numeric value. Integer.parseInt throws an exception for this reason, so we need to handle this case. For our example we'll just print a message and skip the value.
try {
int num = Integer.parseInt(numbersInAList.get(ndx));
} catch (NumberFormatException formatException) {
System.out.println("Oops, that's not a number");
}
We want this new num to be placed in an array, so we'll place it inside the array we defined
numbers[ndx] = num;
or combine the last two steps
numbers[ndx] = Integer.parseInt(numbersInAList.get(ndx));
Final Result
If we combine all of the code from "Step by Step", we get the following
List<String> numbersInAList = Arrays.asList("1", "2", "-3");
int[] numbers = new int[numbersInAList.size()];
for (int ndx = 0; ndx < numbersInAList.size(); ndx++) {
try {
numbers[ndx] = Integer.parseInt(numbersInAList.get(ndx));
} catch (NumberFormatException formatException) {
System.out.println("Oops, that's not a number");
}
}
Important Considerations
Note there are more elegant solutions, such as using Java 8 streams. Also, it's typically discouraged to store ints as Strings, but it can happen, such as reading input.
I can't see where you call setLocationCells(ArrayList<String>) in your code, but if the only problem is storing integers into an ArrayList there is a solution:
ArrayList<Integer> myArray = new ArrayList<Integer>();
myArray.add(1);
myArray.add(2);
It is true that you can't use primitive types as generics, but you can use the Java wrapper types (in this case, java.lang.Integer).
Related
I have a program utilize swing GUI and new sort algorithms and searches. My sorts work fine however when trying to search for numbers I have it give a message whether it has been found or not. However rather saying its found when the number exists, it says its not found.Also for some reason it only says that 0 is found at index 4.
static int Numbers[]=new int[0];
private static class ButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
//get data
String data = txtInput.getText();
//parse for numerical value
int numGenerate = Integer.parseInt(data);
int Numbers[]=new int[numGenerate];
String command = e.getActionCommand();
if (command.equals("Sort"))
{
String unSortedData="";
//ouput unsoted data
for (int x=0;x<=Numbers.length-1;x++)
{
Numbers[x]=(int)(Math.random()*2001)-1000;
unSortedData+=(Numbers[x]+",");
}
txtUnsorted.setText(unSortedData);
if (btnQuickSort.isSelected())
{
QuickSort(Numbers,0,Numbers.length-1);
}
if (btnMergeSort.isSelected())
{
MergeSort(Numbers,0,Numbers.length-1);
}
if (btnInsertionSort.isSelected())
{
InsertionSort(Numbers);
}
if (btnSelectionSort.isSelected())
{
SelectionSort(Numbers);
}
if (btnShellSort.isSelected())
{
ShellSort(Numbers);
}
if (btnShakerSort.isSelected())
{
ShakerSort(Numbers);
}
generated=true;
}
if (command.equals("Search"))
{
//get data
String data2 = txtSearch.getText();
//parse for numerical value
int FindNum = Integer.parseInt(data2);
if (generated==true)
{
int counter=0;
for (int x=0;x<Numbers.length;x++)
{
if (Numbers[x]==FindNum)
{
lblSearch.setText("Status: Found "+ FindNum+ "at index "+ counter );
}
counter++;
}
}
else
{
lblSearch.setText("Status:Error! Enter or sort a number");
}
}
}
}
At the moment you are only populating the array with random numbers if you run the 'search' component. I suggest splitting the generation and the two operations into separate methods:
private int[] randomNumbers(int size) {
Random random = new Random();
int[] numbers = new int[size];
for (int i = 0; i < numbers.length; i++)
numbers[i] = random.nextInt(2000) - 1000;
unsortedData = Arrays.toString(numbers);
}
public void actionPerformed(ActionEvent e) {
int[] numbers = randomNumbers(Integer.valueOf(txtInput.getText());
switch(e.getActionCommand()) {
case "sort":
...
break;
case "search":
...
break;
}
}
Note that there is a simpler way of getting an array of random integers:
int[] numbers = random.ints(size, -2000, 2000).toArray();
But I'm assuming you're not using streams yet.
In actionPerformed(), a new local variable named "Numbers" is defined by "int Numbers[]=new int[numGenerate]" which masks global variable "Numbers".
And when you delete "int" and use "Numbers =new int[numGenerate]", the global variable "Numbers" can be used here and program works as you expect.
I'm currently trying to working through a problem with ArrayList.
This is supposed to take the input of the user and customers sales and display the top customer. Yet, I'm having and issue with an inner while.
Using VSCODE. The inner while is throwing an error within the inner if sales.get(j) > largest) stating the > is undefined.
Please, any help would be greatly appreciated.
import java.util.ArrayList;
import java.util.Scanner;
public class TopCusomters {
public static void main(String[] args)
{
ArrayList sales = new ArrayList();
ArrayList customers = new ArrayList();
int numOfItems = 0;
double price = 0;
Scanner in = new Scanner(System.in);
boolean entryComplete = false;
do {
System.println("Customers Names");
customers.add(in.next());
System.println("Sales of the Customer (0 to end):");
price = in.nextDouble();
sales.add(price);
numOfItems++;
}while(price != 0 && mumOfItems < 100);
System.out.println("Please provide values of N");
int topN = in.nextInt();
ArrayList topCustomers = nameOfBestCustomers(sales, customers, topN);
System.out.println(" Top Customers list" + "is" + topCustomers.toString());
}
public static ArrayList nameOfBestCustomers (ArrayList sales,ArrayList customers, int topN)
{
ArrayList bestCustomers = new ArrayList();
sortCustomers(sales,customers);
int i = 0;
while (i)
{
bestCustomers.add(customers.get(i));
i++;
}
return bestCustomers;
}
public static void sortCustomers(ArrayList sales, ArrayList customers)
{
int i = 0;
double temp = 0;
String tempName = "";
while (i)
{
double largest = sales.get(i);
int largestIndex = i;
int j = i;
while (j)
{
if(sales.get(j) > largest)
{
largest = sales.get(j);
largestIndex = j;
}
i++;
}
temp = sales.get(i);
sales.set(i,sales.get(largestIndex));
sales.set(largestIndex,temp);
tempName = customers.get(i);
customers.set(i,customers.get(largestIndex));
customers.set(largestIndex, tempName);
i++;
}
}
}
You are not specifying object types that lists are holding for below declarations ,
ArrayList sales = new ArrayList();
ArrayList customers = new ArrayList();
So when you retrieve objects from list and try to apply operators, Java doesn't know which type its working on. ( Java assumes java.lang.Object and operator > doesn't make sense on Object )
For long term solution , declarations should be changed as below or you can try that after explicit cast too,
List<Double> sales = new ArrayList<>();
List<String> customers = new ArrayList<>();
where Double is java.lang.Double
ArrayList without type will default to ArrayList<Object>, that means that sales.get(j)'s return value is Object. You probably want ArrayList<Double>.
You have multiple syntax errors, for example:
Conditional expression like while (<expr>) { ... } need to evaluate to boolean. while(i) is not a valid expression, see
The while and do-while Statements docs.
do { ... } is not a valid Java construct, most likely you tried to use a do-while loop do { ... } while (<expr>); loop.
You are using rawtype ArrayList. Most likely it should be List<Double>. You need generics to compare sales elements with double largest using auto-boxing, see Lesson: Generics (Updated) docs.
I am attempting to output the contents of an ArrayList, but no matter which approach I try I seem get the location of the Array rather than the contents of the Array. Running each of the following together gives me:
run:
[[Ljava.lang.String;#55f96302, [Ljava.lang.String;#232204a1, [Ljava.lang.String;#4554617c, [Ljava.lang.String;#7f31245a, [Ljava.lang.String;#2503dbd3, [Ljava.lang.String;#5cad8086]
[Ljava.lang.String;#232204a1
[Ljava.lang.String;#232204a1
[Ljava.lang.String;#232204a1
Here's the code snippet:
// Each of the following approaches results in
// [Ljava.lang.String;#232204a1
// instead of the actual value of the ArrayList.
String test = accountNumbers.get(1);
System.out.println(test);
System.out.println(accountNumbers.get(1));
System.out.println(accountNumbers.get(1).toString());
// This actually outputs:
// [[Ljava.lang.String;#55f96302, [Ljava.lang.String;#232204a1, [Ljava.lang.String;#4554617c, [Ljava.lang.String;#7f31245a, [Ljava.lang.String;#2503dbd3, [Ljava.lang.String;#5cad8086]
String str = Arrays.toString(accountNumbers.toArray());
System.out.println(str);
I'm not really sure what's causing this. Is there some way to get the contents to display?
EDIT: Here's the entire method. An answer on another question (here) advised me to try using ArrayList instead of the approach I was using. I adapted the suggestion, but I felt that the problems were better placed in a new question rather than as an edit to that question.
protected static void loadAccountInformationFromFile() throws Exception
{
Scanner account = new Scanner(new File(INPUT_ACCOUNT_FILE)).useDelimiter(",");
int sortCount = 1;
List<String> accountNumbers = new ArrayList<>();
List<String> firstNames = new ArrayList<>();
List<String> lastNames = new ArrayList<>();
List<String> balances = new ArrayList<>();
List<String> lastVariables = new ArrayList<>();
do {
String[] temp1 = account.next().split(",");
String temp2 = "" + temp1;
if (sortCount == ACCOUNT_NUMBER_COUNT) {
accountNumbers.add(temp2);
} else if (sortCount == FIRST_NAME_COUNT) {
firstNames.add(temp2);
} else if (sortCount == LAST_NAME_COUNT) {
lastNames.add(temp2);
} else if (sortCount == BALANCE_COUNT) {
balances.add(temp2);
} else if (sortCount == LAST_VARIABLE_COUNT) {
lastVariables.add(temp2);
}
if (sortCount < MAX_VALUES_PER_LINE) {
sortCount++;
} else {
sortCount = 1;
}
} while (account.hasNext());
// Each of the following approaches results in
// [Ljava.lang.String;#232204a1
// instead of the actual value of the ArrayList.
String test = accountNumbers.get(1);
System.out.println(test);
System.out.println(accountNumbers.get(1));
System.out.println(accountNumbers.get(1).toString());
// This actually outputs:
// [[Ljava.lang.String;#55f96302, [Ljava.lang.String;#232204a1, [Ljava.lang.String;#4554617c, [Ljava.lang.String;#7f31245a, [Ljava.lang.String;#2503dbd3, [Ljava.lang.String;#5cad8086]
String str = Arrays.toString(accountNumbers.toArray());
System.out.println(str);
account.close();
// I want to adapt what I previously used to access the ArrayLists.
// Bank bank = new Bank();
//
// bank.openAccount(new CheckingAccount(10100, new Customer("Adam", "Apple"),500.00,false));
// bank.openAccount(new CheckingAccount(10101, new Customer("Beatrice", "Bagel"),2000.00,true));
// bank.openAccount(new SavingsAccount(2010, new Customer("Adam", "Apple"),5000.00,0.02));
}
EDIT 2: Here are the class variables:
private final static String INPUT_ACCOUNT_FILE = "accountInfo.txt";
private static final int ACCOUNT_NUMBER_COUNT = 0;
private static final int FIRST_NAME_COUNT = 1;
private static final int LAST_NAME_COUNT = 2;
private static final int BALANCE_COUNT = 3;
private static final int LAST_VARIABLE_COUNT = 4;
private final static int MAX_VALUES_PER_LINE = 5;
EDIT 3: For the benefit of those who may read this question late and be confused by some of the comments on the correct answer, part of my issue was related to an issue with the text file itself. This is an example of the formatting of the text file:
10100,First,Last,Balance,value
10101,First,Last,Balance,value
20100,First,Last,Balance,value
Also: To get the ArrayLists to store the correct strings I had to change sortCount from:
int sortCount = 1;
to
int sortCount = 0;
Because when it was set at 1 it would store the first name in the account number string.
The problem is not in your "displaying" but in the way you read the contents from the file.
Your code prints out correctly "addresses" because the strings in accountNumbers instance are really these values (because you put array of strings into one single string). So what really happens is that in your temp2 String is your temp1.toString().
You are using wrong delimiter (you should use default one for whitespaces instead):
Scanner account = new Scanner(new File(INPUT_ACCOUNT_FILE));
And then assign values like:
if (temp1.length > ACCOUNT_NUMBER_COUNT) {
accountNumbers.add(temp1[ACCOUNT_NUMBER_COUNT]);
if (temp1.length > FIRST_NAME_COUNT) {
firstNames.add(temp1[FIRST_NAME_COUNT]);
if (temp1.length > LAST_NAME_COUNT) {
lastNames.add(temp1[LAST_NAME_COUNT]);
if (temp1.length > BALANCE_COUNT) {
balances.add(temp1[BALANCE_COUNT]);
if (temp1.length > LAST_VARIABLE_COUNT) {
lastVariables.add(temp1[LAST_VARIABLE_COUNT]);
}
Your temp2 and sort variables are not needed.
Anyway it is a bit weird to use these collections. I would rather suggest to do it like:
Scanner scanner = new Scanner(new File(INPUT_ACCOUNT_FILE));
Collection<Account> bank = new ArrayList<>();
while (scanner.hasNext()) {
String[] fields = scanner.next().split(",");
if (fields.length < MAX_VALUES_PER_LINE) {
continue; // incomplete row, skip it or maybe throw some exception?
}
String number = fields[ACCOUNT_NUMBER_COUNT];
Customer customer = new Customer(fields[FIRST_NAME_COUNT], fields[LAST_NAME_COUNT]);
double balance = Double.valueOf(fields[BALANCE_COUNT]);
String type = fields[LAST_VARIABLE_COUNT];
Account a = null;
switch (type) {
case "N": {
a = new CheckingAccount(number, customer, balance);
break;
}
case "0.02": {
a = new SavingsAccount(number, customer, balance);
break;
}
default: {
continue; // unknown type of account, skip it or maybe throw some exception?
}
}
bank.add(a);
}
String temp2 = "" + temp1;
You are trying to concat a blank with a string array, this is equals with
String temp2 = "" + temp1.toString();
Note that toString() of Array will return object references, not the value.
So you should try to convert array to some Java Collection class that implements the toString() method like ArrayList
String temp2 = "" + Arrays.asList(temp1).toString();
or you can also do
String temp2 = "" + Arrays.toString(temp1);
Both will give you the String value (and some "[" and "]" too, I guess, because of the toString() implementation of ArrayList and Arrays, you can work it out).
This question already has answers here:
How to read array of integers from the standard input in Java?
(2 answers)
Closed 8 years ago.
So my code looks like this so far:
public class PancakeSort {
public static int flip(int n) {
int temp = 0;
for (int i = 0; i < (n+1) / 2; ++i) {
int[] pancakes = new int[n];
temp = pancakes[i];
pancakes[i] = pancakes[n-i];
pancakes[n-i] = temp;
}
return temp;
}
public static void sort (int[] pancakes) {
for (int i=0; i<pancakes.length; i++){
if (pancakes[i] > pancakes[i+1]){
flip(i+1);
}
}
System.out.println(pancakes);
}
public static void main(String[] args) {
}
}
But how I input a whole array of integers using standard input (StdIn.readLine())? I understand that the code might not be correct and I'm working on figuring that out,and I'm also aware that this question has been asked before in this site, but not specifically using the standard library and that is where I'm stuck.
You can send integer array as input
PancakeSort pancakeSort = new PancakeSort();
pancakeSort.sort(new int[] { 100, 50, 89, 2, 5, 150 });
or Use scanner class as
int arr[] = new int[10];
Scanner sc = new Scanner(System.in);
int i = 0;
while (sc.hasNextInt()) {
arr[i] = sc.nextInt();
i = i + 1;
}
PancakeSort pancakeSort = new PancakeSort();
pancakeSort.sort(arr);
But in last case you must not increased the size of array.Otherwise it will give arrayIndexOutOfBoundException
I believe you may be referencing StdIn such as a class like this one?
http://introcs.cs.princeton.edu/java/stdlib/StdIn.java.html
If so, then to get an int from the console you just call StdIn.readInt. An example of how you could approach this is:
public static void main(String[] args)
{
System.out.println("Enter number of pancakes, or enter 0 to quit");
int[] pancakeArray = new int[0];
while (true)
{
try
{
int entry = StdIn.readInt();
if (entry == 0)
{
break;
}
int[] expandedArray = new int[pancakeArray.length + 1];
System.arraycopy(pancakeArray, 0, expandedArray, 0, pancakeArray.length);
expandedArray[pancakeArray.length] = entry;
pancakeArray = expandedArray;
}
catch (Exception e)
{
System.out.println("Invalid entry detected, closing input");
break;
}
}
System.out.println("Pancake array length: " + pancakeArray.length);
sort(pancakeArray);
System.out.println("Final pancake array in order:");
for (int entry : pancakeArray)
{
System.out.println("Pancake value: " + entry);
}
}
This would read int after int until they entered 0 or an invalid value, then it would call your sort routine from there. There are issues in your sort routine but you said you wanted to look at that, so I will let you figure that part out.
I have an array of string objects that was read from a file. Some of these strings I need to use as ints. I wrote a method to read the file but now I just don't know how to get the numbers from the file, here is the file
29,,
Chute,1,0
Chute,2,0
Chute,3,0
Chute,4,0
Chute,5,0
Chute,6,0
Chute,7,0
Chute,8,0
Chute,9,0
Chute,0,1
Chute,0,2
Chute,0,3
Chute,9,1
Chute,9,2
Chute,9,3
Ladder,0,5
Ladder,1,5
Ladder,2,5
Ladder,3,5
Ladder,4,5
Ladder,5,5
Ladder,6,5
Ladder,7,5
Ladder,8,5
Ladder,9,5
Ladder,9,6
here is my method
public void readBoard(String file)throws FileNotFoundException
{
File clboard = new File ("myBoard.csv");
Scanner x = new Scanner(clboard);
while(x.hasNext())
{
String c = x.nextLine();
String [] myboard =c.split(",");
}
}
Try
int numOne = Integer.parseInt(myboard[1]);
int numTwo = Integer.parseInt(myboard[2]);
immediately after your split line.
String [] myboard = c.split(",");
if (myboard.length < 3) {
// error message
} else {
int i1 = Integer.parseInt(myboard[1]);
int i2 = Integer.parseInt(myboard[2]);
}
You might also want to add a try/catch to handle NumberFormatException (which occurs when you try to convert something that isn't a number).
public void readBoard(String file)throws FileNotFoundException
{
File clboard = new File ("myBoard.csv");
Scanner x = new Scanner(clboard);
while(x.hasNext()) {
List<Integer> number = new ArrayList<Integer>();
String c = x.nextLine();
String [] myboard =c.split(",");
for (String candid8 : myboard) {
try {
number.add(Integer.parseInt(candid8));
} catch (NumberFormatException e) {
}
}
}
}
Your numbers will now be in the number object, which is a List. If it's a more complex grammar, look into jflex, as that seems to be the recommendation of Google.