Value of Arraylist is unexpected - java

I have this method that adds temp to xy array.
public void printBoard(int temp[][],int type){
if(type == 1) {
xyArray.add(new Array(temp));
numberOfSolutionsXY++;
}
}
xyArray is global and declared as
public ArrayList<Array> xyArray = new ArrayList();
When I check its value before exiting the method printBoard, it prints the expected 2d array. But when I go to another method, the value of xyArray is different. It has the value of the other Arraylist.
I checked back and forth many times, I did not just mistype the parameter. It's not happening only on xyArray, the same happens to other arraylists: regArray, xArray and yArray
This is how I check the value
System.out.println("\n xy \n"+xyArray.toString());
I do solveBoard method and tries to add the expected value of arrays but different values were appended. They were all the same.
problemArray.add(new Array(board));
solveBoard(board,0,0,4);
if(numberOfSolutions>0)
solutionArray.add(new ArrayList(regularArray));
solveBoard(board,0,0,3);
if(numberOfSolutionsX>0)
solutionArray.add(new ArrayList(xArray));
if(dimension%2==1){
solveBoard(board,0,0,2);
if(numberOfSolutionsY>0)
solutionArray.add(new ArrayList(yArray));
solveBoard(board,0,0,1);
if(numberOfSolutionsXY>0)
solutionArray.add(new ArrayList(xyArray));
}
solutionsArray.add(new ArrayList(solutionArray));
System.out.println("\nsolutions\n"+regularArray.toString());
All of them have the value of problemArray. Even though i placed problemArray.add(new Array(board)); at the bottom, they still get its value.
This is the class Array i've made
public class Array {
int[][] array;
public Array(int[][] initialArray){
array = initialArray;
}
public String toString(){
String x = "";
for(int i = 0;i<array[0].length;i++){
for(int j = 0;j<array[0].length;j++)
x+=array[i][j];
x+="\n";
}
return x;
}
}
Full code here

Try to rename your "Array" class, for example to "MyArray"
And i suppose there are some troubles with Array class constructor.
Try to copy initialArray in to your local variable.
public class MyArray {
int[][] localArray;
public MyArray(int[][] initialArray) {
localArray = initialArray.clone();
for (int i = 0; i < initialArray.length; i++) {
localArray[i] = initialArray[i].clone();
}
}
public String toString() {
// ...
}
}

Related

How do I count and return only the objects in my ArrayList that are true?

I want to count all the objects that are true and return it (as I have tried to do in countNational. The method I use to assign an object as true/false is in a different class and named NationalMessage. I have pasted it below the main method.
public class Ex6
{
public static int countNational (ArrayList<Message> messageList)
{
int countTrue = 0; //will count those that are true
for (int i = 0; i<= messageList.size(); i++)
{
if(messageList.get(i)==true) //GETTING ERROR SAYING CAN'T COMPARE BOOLEAN
countTrue = countTrue + 1;
}
return countTrue;
}
public static void main(String[] args)
{
ArrayList<Message> messageList = new ArrayList<Message>();
messageList.add(new NationalMessage("UKJohn","UKMark","aa"));
messageList.add(new NationalMessage("UKJohn","FRJean","aa"));
messageList.add(new Message("Mike","John","aa"));
System.out.println(countNational(messageList));
}
}
************************* THE BELOW IS A METHOD FROM A SEPERATE CLASS CALLED NATIONAL MESSAGE*****************************
public NationalMessage(String ssender, String rreceiver, String ccontent)
{
super(ssender,rreceiver,ccontent);
if (ssender.equals("UK") && rreceiver.equals("UK"))
{
isNational = true;
}
else
{
isNational = false;
}
}
using a stream in java8 is jsut as simple as filtering the list
long xx = myList.stream().filter(t -> t.isNational).collect(Collectors.counting());
or to get the list
List<NationalMessage> x = myList.stream().filter(t->t.isNational).collect(Collectors.toList());
Change:
if(messageList.get(i)==true)
to:
if(messageList.get(i).isNational==true)
Why?
Because you can compare apples with apples and oranges with oranges.
On right hand side of == , true is present. So on left hand side also there should be a boolean or an expression that results in a boolean.
Your original expression messageList.get(i) does not result in a boolean. Rather it results in an object or null.
In some languages like C, a null may be interpreted as false and non-null may be interpreted as true but in Java, it's not so.
You have to be explicit about the booleans.
For e.g. left hand side expression in your case could be :
messageList.get(i)!=null which would evaluate to true/false

return value from recursive method

I have a recursive method that i would like to return a value from when a specific if statement returns true (which it always does)
if (compactArray != null) {
if (arrayCount == (compactArray[0].length - 1)) {
return compactArray;//i want to return here
}
}
But Java wont let me return from the if, and throws a warning that i need to add a return value.
What does one do? The full method is as follows
public String[][] diXmlRecursiveRead(Iterator<Element> list, String[] columnNames, String[][] compactArray,
Integer arrayCount) {
Element element = null;
String[] columns = null;
while (list.hasNext()) {
element = list.next();
// Assign data to the two dimensional array, starting from position
// 1 in the length to not overwrite the column names.
// This is also where i would print the column name plus its
// attribute value if i was printing to console.
if (columnNames != null) {
for (int a = 0; a < columnNames.length; a++) {
compactArray[a][arrayCount] = element.getAttributeValue(columnNames[a]);
}
}
// Find the element that contains the columns="" information
if (element.getAttributeValue("columns") != null) {
// reset the array count, since we are processing a new
// columns="" section
arrayCount = 1;
columns = element.getAttributeValue("columns").toString().split(",");
// set width size +1 to make room for the column names
// (columnNames + data +1)
compactArray = new String[columns.length][element.getChildren().size() + 1];
// Set the EVE column names in the first column of the two
// dimensional array
for (int a = 0; a < columns.length; a++) {
compactArray[a][0] = columns[a];
}
}
// After added the last value to the two dimensional array return the
// array[][]
if (compactArray != null) {
if (arrayCount == (compactArray[0].length - 1)) {
return compactArray;//i want to return here and not at the end!
}
}
// Method calls itself with a new level of the child
diXmlRecursiveRead(element.getChildren().iterator(), columns, compactArray, arrayCount++);
}
//Java want me to return here!!
}
look at that example:
static int count = 0;
private static boolean foo() {
if (count == 5) {
return true;
}
count ++;
return foo();
}
note that the recursive call is called with the 'return' statement.
Think about the stack that is being build when you execute a recursive method. at some point all methods need to start returning a value up the stack.
You need to pass through the String[][] compactArray parameter and return that. This is the result of your method that will be returned at the end.
Returning starts when the deepest level of recursion is done. Then everything is passed through till the first call of your method.
Added some code:
package recursion;
import java.util.Iterator;
import java.util.LinkedList;
import javax.xml.bind.Element;
class Recursionat0r {
static private int threshhold = 3;
public static void main(String[] grmlZ) {
Recursionat0r recursionat0r = new Recursionat0r();
String[] columnNames = { "hello", "world" };
String[][] compactArray = new String[4][10]; // would recommend
// ArrayList here
compactArray = recursionat0r.diXmlRecursiveRead(null, columnNames, compactArray, 0);
recursionat0r.printCompactArray(compactArray);
}
public String[][] diXmlRecursiveRead(Iterator<Element> list, String[] columnNames, String[][] compactArray,
Integer arrayCount) {
String[] columns = columnNames;
// append stuff to array
// compactArray[a][arrayCount] =
compactArray[arrayCount] = columnNames;
// Method calls itself with a new level of the child
// this is a _recursion step_
// OR
// Method returns the compactArray!
// this is the _recursion ancor_
if (arrayCount < threshhold) {
System.out.println("returning diXmlRecursiveRead");
return diXmlRecursiveRead(null, columns, compactArray, ++arrayCount);//increment arrayCount BEFORE passing ;) - else it gives stackoverflow (haha)
// Java want me to return here!!
} else {
System.out.println("returning the compactArray");
// _recursion anchor_
return compactArray; // this marks the end of the recursion
// values start to be passed back from here
// you might want to specify another condition for the anchor to be
// thrown ;)
}
}
public void printCompactArray(String[][] compactArray){
for(int count = 0; count < compactArray.length; count++){
for(int inside=0; inside < compactArray[0].length; inside++) //warning assuming all Arrays in compactArray have the same length
System.out.println(compactArray[count][inside]);
}
}
}
This yields:
returning diXmlRecursiveRead
returning diXmlRecursiveRead
returning diXmlRecursiveRead
returning the compactArray
hello
world
hello
world
hello
world
hello
world
Hope this helps ^^-d
I think you may need to add a default return value to your method.
The compiler needs to know wich value to return when your 'if' test fails.
You could just add a return value at the end, just to make the compiler relax. This happens because, if the "if" clause is false, then you return nothing from this function. I guess this is a base case return, right?
Change:
// Method calls itself with a new level of the child
diXmlRecursiveRead(element.getChildren().iterator(), columns, compactArray, arrayCount++);
to
// Method calls itself with a new level of the child
return diXmlRecursiveRead(element.getChildren().iterator(), columns, compactArray, arrayCount++);
Note the added return di....
If a method returns a value then ALL routes through the code must return something. In your case only the deepest level of recursion will return something. All the others would just throw away the value discovered.

java- Cycle between two arrays using for and while loop

I am having difficulty with my program. Some help would be appreciated.
I have 3 arrays, 2 that store emotions and 1 that stores names. The 2 names in the names array correspond to each of the two emotion arrays. I want to use a for loop and a while loop to change these for each name. Currently what I have is :
public static int [] showhunger(int [] i, int [] m,String [] x)
{ String ans = "yes";
for (int j=0;j<names.length;j++)
{ while(ans.equals("yes")||ans.equals("Yes")||ans.equals("y")||ans.equals("Y"))
{ if (i[0]<=-1)
{ JOptionPane.showMessageDialog(null,"Stop "+x[j]);
}
ans=JOptionPane.showInputDialog("Feed "+x[j]+"?");
if (ans.equals("yes")||ans.equals("Yes")||ans.equals("y")||ans.equals("Y"))
{ i[0]-=1;
}
}
}return i;
}
I cannot get the for loop to cycle between the two integer arrays. Also I'd like to know how I can return both arrays
your code should have more comments inside, to explain your loops .
you can not return 2 arrays, but if you change them in your method, they are changed.
if you want to really return something:
you can return an object with that for example
public class bundle
{
public int A[];
public int B[];
}
public static bundle showhunger(...)
{
// ...
bundle bdl=new bundle();
bdl.A=new int[10];
bdl.B=new int[10];
// populate
return bdl;
}

Array in Method Header: error ']' expected (Java)

I'm quite new to arrays and methods, and I've been seeing this error recurring through several programs: error '[' expected.
In each occasion, it seems to correct itself as I adjust something else, but in this particular case, I am completely stumped.
By the way, I am using several methods and arrays to create a quiz (before you ask, yes, this is an assignment and I agree, a list is a better way to handle this data - but that is not an option).
It is possible that I am not passing the arrays correctly between methods, as I'm a little muddy on that process. From my understanding, in order to send/receive (i.e. import/export) an array or other variable between methods, I must declare that variable/array in the method header parameters.
import java.util.Scanner;
public class H7pseudo
{
public static void main(String[] args)
{
//call getAnswerkey method
getAnswerkey(answerkey[i]);
//call getAnswers method
getAnswers(answers[i]);
//call passed method? necessary or no?
boolean passed = passed(answerkey[i], answers[i], qMissed[i], points);
//Print results of grading
if (passed)
{
System.out.println("Congratulations! You passed.");
}
else
{
System.out.println("Try again, sucka. You FAILED.");
}
//call totalPoints
totalIncorrect(points);
//call questionsMissed
questionsMissed(qMissed[i]);
}
//get answer key (create answerkey array & export)
public static void getAnswerkey(answerkey[i])
{
//create answerkey array here
char[] answerkey;
//determine number of questions (indices)
answerkey = new char[20];
//input values (correct answers) for each index
//for our purposes today, the answer is always 'c'.
for (int i = 0; i <=20; i++)
{
answerkey[i] = 'c';
}
}
//get student answers (create answers array & export)
public static void getAnswers(answers[i])
{
//initialize scanner for user input
Scanner scan = new Scanner(System.in);
//create answer array here
char[] answers;
//determine number of questions (indices)
answers = new char[20];
//prompt for user input as values of each index
for (int i = 0; i <= 20; i++) {
answers[i] = scan.nextChar();
}
}
//grade student answers (import & compare index values of arrays:answers&answerkey
//create & export qMissed array
public static boolean passed(answerkey[i], answers[i], qMissed[i], points)
{
int points = 0;
//create new array: qMissed
boolean[] qMissed;
//determine number of questions to be graded
qMissed = new boolean[20];
//initialize values for array
for (int i = 0; i <= 20; i++) {
qMissed[i] = false;
}
//cycle through indices of answerkey[i] & answers[i];
for (int i = 0; i =< 20; i++)
{
if (answers[i] == answerkey[i])
{
correct = true;
points = points+1;
qMissed[i] = true;
}
else {
qMissed[i] = false;
}
}
//evaluate whether or not the student passed (15+ correct answers)
if (points >= 15)
{
passed = true;
}
else
{
passed = false;
}
return passed;
}
public static void totalIncorrect(points)
{
int missed = 20 - points;
System.out.println("You missed " + missed + " questions.");
}
public static void questionsMissed(qMissed[i])
{
// for each index of the array qMissed...
for (int i = 0; i < qMissed.length; i++)
{
//...print correct and false answers.
system.out.println(i + ": " + qMissed[i] + "\n");
}
}
}
You can't define array size in the method signature, in Java.
public static void getAnswerkey(answerkey[i])
You can't put anything inside the [] in a method declaration. Also, you have to mention the type:
public static void getAnswerKey(char[] answerkey)
This is not the only reason your code won't work as intended, but I'll leave the rest as part of the exercise.
Look at your method definitions:
public static void questionsMissed(qMissed[i])
This is wrong. You should define the type of the variable and it should not contain [i] like an element of an array. It should be something like this:
public static void questionsMissed(int qMissed)
Or if you want to pass the array, write it like this:
public static void questionsMissed(int[] qMissed)
Apart of this, there are other several errors in your code:
getAnswerkey(answerkey[i]); //answerkey is not defined
getAnswers(answers[i]); //answers is not defined
It would be better if you start reading a Java tutorial first.
I want to vote up Luiggi's answer, but I don't have enough reputation to do that :)
Congrats, cordivia, on getting started with Java!
Here is how an array is declared:
type[] arrayName = new type[numberOfElements]
For example, you did this right in your method definition for getAnswerkey():
char[] answerkey;
answerkey = new char[20];
The part in the method definition inside the parentheses defines the kind of data the method is willing to accept from the outside. So if you don't need to put something into the method to get something out of it, you don't need to put anything in the parentheses. Define the method like this:
getAnswerkey() {
...But that's not the whole story. If you want to get something out of the method, it needs to have a return type as well. A return type is what you're gonna get out of the method when the method's done doing it's magic. For example, if you want to get an int array out of a method you would do something like this:
public static int getTheInteger() {
Since you want an array of chars from the method, you'll want to do something like this:
public static char[] getAnswerkey() {
So that's how you get a method to give you something back. If don't want anything back, you put void:
public static void noMarshmallows() {
Now, when you use the method, you're gonna need to do something with what it gives you, or it did all that work for nothing. So you need to store the return value in a variable when you call the array (calling methods is what you've been doing in main). You know how to store something in a variable. You use the '=' operator:
int myVeryFavoriteNumber;
myVeryFavoriteNumber = 5;
So, you do the same thing when you're getting something out of an array. You assign the return value to a variable. If you want to do this with an array, do this:
int[] myFavs;
myFavs = getMyFavoriteNumbers();
Same with chars:
char[] answerKey;
answerKey = getAnswerKey();
Voila! Your answer key is now right out in the open for the rest of main to see :)
Now, if you want to put something into a method and have it do something with what you put in, you define a parameter. You know how this works. It's just like declaring a variable, and that's exactly what it is. Parameters go in the parentheses and only the method using the parameter sees that variable name (it's local). Something like this:
public static void plusOneToAll (int[] numbers) {
for (int i = 0; i < numbers.length; i++) {
numbers[i] = numbers[i] + 1;
}
}
Notice int[] numbers in the parentheses. The type being passed in is int[] or integer array. numbers is just the parameter name. It functions just like a variable, but it is declared locally (inside the parentheses) and use locally (inside the method). So, if you wanted to compare the answers from two arrays and return the number of matches (like a total score for instance), you would do something like this:
public static int getTotalScore (char[] correctAnswers, char[] userAnswers) {
int totalScore = 0;
for (int i = 0; i < correctAnswers.length; i++) {
if (userAnswers[i] == correctAnswers[i]) {
totalScore = totalScore + 1;
}
}
return totalScore;
}
Notice the return type: int (written before the method name). Inside the array I'm using the variable totalScore to keep track of the number of times the answers match. The method takes two char arrays from the outside and uses them on the inside. Finally, I return an int: totalScore. That kicks the value of totalScore back out to whatever called it (main).
If I might add one last thing: Do yourself a favor and go pick up a copy of Head First Java. It's hard to find a good tutorial online and Java textbooks are just plain boring. The Head First series are kind of like coloring books for adults.
Best of luck!

Return multiple arrays to the main method

My program is suppose to take a text file, read the first four names, create a random number between 1-4, and then assign the names to 4 different teams based on what the random number was. For instance, if the number was 3, then the first name would go to team 3, second name to team 4, etc. etc.(repeat process until there are no more names) I believe I have all of the code for that correct, the problem is I can't figure out how to return all the names I have put into the arrays that were brought into the method. Here is my code:
public static void main(String args[]) throws IOException
{
BufferedReader girlFile = new BufferedReader(new FileReader("girls40.txt"));
PrintWriter teamFile = new PrintWriter(new FileWriter("xxxxxxx-teamlist.txt"));
String team1[] = new String[20];
String team2[] = new String[20];
String team3[] = new String[20];
String team4[] = new String[20];
int n;
n = loadTeams(team1,team2,team3,team4,girlFile);
girlFile.close();
teamFile.close();
}
public static String[] loadTeams(String team1[],String team2[],String team3[],String team[],BufferedReader girlFile)
{
int n;
int random;
String name1;
String name2;
String name3;
String name4;
while((name1=girlFile.readLine())!=null)
{
name2=girlFile.readLine();
name3=girlFile.readLine();
name4=girlFile.readLine();
random = 1 + (int)(Math.random() * 4);
if(random==1)
{
team1[n]=name1;
team2[n]=name2;
team3[n]=name3;
team4[n]=name4;
}
if(random==2)
{
team1[n]=name4;
team2[n]=name1;
team3[n]=name2;
team4[n]=name3;
}
if(random==3)
{
team1[n]=name3;
team2[n]=name4;
team3[n]=name1;
team4[n]=name2;
}
if(random==4)
{
team1[n]=name2;
team2[n]=name3;
team3[n]=name4;
team4[n]=name1;
}
n++;
}
return team1[],team2[],team3[],team4[];
}`
The main method was given to me, so it cannot be changed.
If there is more code in main method than you've posted here. You'll have to mention what is the variable n and how is it being used else follow the answer.
main Method can't be changed
In your main method,
int n;
n = loadTeams(team1,team2,team3,team4,girlFile);
girlFile.close();
teamFile.close();
} // End of Main Method
You have not used returned value n for nothing. So it really doesn't matter what you return from method loadTeams() as long as it is an int.
Also, here loadTeams() returns an String[] which can't be assigned be int n, you'll have to change return type of loadTeams() to int as
public static int loadTeams(String team1[],String team2[],String team3[],String team[],BufferedReader girlFile) {
/*
...
*/
return 0; // whatever, it isn't being used
}
This the solution if you can't change the main method.
The call to loadTeams() expects a return value of type int. Not an array or multiple arrays. If you can't change the main method then loadTeams should return an integer.
// ...
int n;
n = loadTeams(team1,team2,team3,team4,girlFile);
// ...
you don't have to return anything, arrays created in main() will be passed to your method by reference, you can fill them there, and after execution of your method, values will be kept in these arrays
The loadTeams should return an int and not String[].
There is no need to return arrays. Changes made in the arrays in the loadTeams methods will be reflected back to the array in main method.

Categories