I am trying to do check if an array is full and print out to the user he is unable to enter more books.
static Object[][] books=new Object[2][];
I am asking 3 values from the user and am storing to another array called "row".
Object[]row=new Object[3];
After that i loop through the books array and check if it has a null value inside of it and add the "row" array with the given values of the user.
the problem am having is i cant give any feedback if books array is full after entering two rows of values.
boolean empty=false;
while(empty==false){
for (int i = 0; i < books.length; i++) {
if(books[i]==null){
books[i]=row;
empty=true;
break;
}
}
}
Why not having a variable
int bookCounter = 0;
which you can increase/decrease everytime you add/delete books and then just check it against your max number of books (which I assume is books.length)
In this way you don't need to loop over the array, which is not efficient.
There is no need for the while loop. After the for loop ends, check your empty variable that you're already setting. If it's false, then give your feedback to the user.
Arrays are always full. Even each element is null. If you initialize it with the size of 10, then JVM will alocate memory and fill the all the arrays positions with default value. What is: 0 for primitives numbers and char type, false for primitive boolean type and null for Objects.
So, your code won't work with a int[] for instance. Because there won't exist any null element.
That's why you dont have a count() method... You can create a method that is named countNotNull(). But you'll need to interate for all the array long.
The best solution is to use a variable to count when you add/remove itens form array. As
Guillermo Merino said.
Related
I need a recursive solution which returns any combination of n subset from k set (in mathematical sense). I have an ArrayList and I want return any possible n-size subsets from recursive method. Order doesn't matter.
So if I have set of employees {Jim, Tom, Ann, John} and want 2 of them I should get:
{Jim Tom}{Jim Ann}{Jim John}{Tom Ann}{Tom John}{Ann John}
I found this https://stackoverflow.com/a/16256122/10929764
but it only prints out result. I modified it a bit to add any combination to ArrayList and return it, but it doesn't work properly.
Here is a code:
public ArrayList<Employee[]> combinationsOfEmployee(ArrayList<Employee>sourceList, int selected, int startIndex, Employee[] result, ArrayList<Employee[]>allResults){
if(selected == 0){
for(int i=0; i<result.length; i++){
System.out.print(result[i].getLastName() + " ");
}
System.out.println("");
allResults.add(result);
return allResults;
}
for(int i=startIndex; i<=sourceList.size() - selected; i++){
result[result.length - selected] = sourceList.get(i);
combinationsOfEmployee(sourceList, selected - 1, i + 1, result, allResults);
}
return allResults;
}
It prints out properly all combinations, but adds the same values all the time to ArrayList. So allResults is
{Ann, John}{Ann, John}{Ann, John}{Ann, John}{Ann, John}{Ann, John}
instead of:
{Jim Tom}{Jim Ann}{Jim John}{Tom Ann}{Tom John}{Ann John}
You are wondering why it prints it fine while the returned list seems to have the exact same array at each position.
That's because it's the exact same array (same reference to the same object). Since in your solution you are using only one array, when you call allResults.add(result), you add the reference to your only array in the list. Then you keep modifying it when you look for the other combinations. That's why your list only contains the last combination found.
The solution to this is to add a new array each time you find a combination by adding a copy of your current array to your list. Simply replace
allResults.add(result);
by
allResults.add(Arrays.copyOf(result, result.length));
That way, every element of your list points to a different array.
So say I have an array with columns {item, quantity}. I am getting these values from an sql table, then sorting them by item. I am using a temporary variable "quantity" to manipulate the double value:
while(rs.next()){
item = rs.getString(1);
for(int i = 0 ; i < array.size ; i++){
if(item.equals(array[i][0]){
double quantity = rs.getDouble(2);
quantity = quantity + Double.parseDouble(array[i][1]);
array[i][1] = quantity;
}
}
//add code for adding items if not found in array
}
My question is will using this temporary variable be slower/create garbage while it iterates the array? Does Java properly dispose of this variable at the end of the if statement? I am asking because I am having issues with heap space, and I do not want to have to rewrite everything to accomodate this.
My other option is:
if(item.equals(array[i][0]){
array[i][1] = String.valueOf(Double.parseDouble(array[i][1]) + rs.getDouble(2));
}
Thanks for reading
It will always override quantity with new value, when old value will be keep of course in array. Quantity won't have impact on your memory especially that this is primitive.
If you will deal with complex type and you will do something like that, you will override with every loop the reference to object, so in array you will have all the time reference to same object.
This question already has answers here:
How to remove specific element from an array [duplicate]
(6 answers)
Closed 8 years ago.
public class Example {
public static void main(String [] args) {
String [] wombology;
wombology = new String[3];
wombology[0] = "History of Wombology";
wombology[1] = "Why Wombology";
wombology[2] = "Wombology and Me";
Random book = new Random(System.currentTimeMillis());
Scanner choice = new Scanner(System.in);
String yourChoice;
do {
System.out.println("Press enter for random book");
yourChoice = choice.nextLine();
if(yourChoice.equals("")) {
System.out.println(wombology[randomizer.nextInt(3)]);
System.out.println();
}
if(yourChoice == "EXIT") {
break;
}
} while(!yourChoice.equals("EXIT"));
}
}
How could I take out a "book" from the array once chosen randomly?
How could I put back in said "book" later back into the array?
Example: "History of Wombology" is randomly chosen and is taken out.
The next random selection should NOT include "History of Wombology" until it is put back in.
Meaning only "Why Wombology" and "Wombology and Me" should be the only possible choices.
I'm assuming that this is homework and an ArrayList is not possible. And I don't want to give a full, detailed answer.
One option might be to create a parallel array, boolean isCheckedOut[], and track your books there.
You need to manage the array yourself. That means you need to know the real size of the array and the filled size. This is because once the array is created the size cannot change.
If you delete an object from the array you need to shift the adjacent elements towards that position.
For example, your array looks like this:
[A|B|C|D|E|F]
allocatedArraySize = 6
currentSize = 6
If you delete C which is at position 2 then you must shift D, E, F to the left. You could also make the last position null.
[A|B|D|E|F|null]
allocatedArraySize = 6
currentSize = 5
To insert, simply use this:
// Check Array is not full.
if(currentSize != allocatedArraySize)
{
// Then add your object to the last position in the array.
array[currentSize] = obj;
// Increment the index.
currentSize++;
}
else
{
// Don't allow insertion.
// Or create a new-bigger-array;
// then copy all elements of the full array into it.
}
You have to "define" an action for "taking out a book" on the technical level. I can image two possibilities for this
setting the array content at the specific position to null
setting the array content at the specific position to an empty string
As the title of most books consists of one or more letters, the empty string-proposal seems also to be valid.
The second task (putting a book back into the array) can be handled in a similar way. Here you have to find an empty place (an array position with an empty string/null as content) and assign the name of the book to it.
Concerning the randomizer and not allowing already removed books: you can use the aforementioned condition to rerun the randomizer, i.e until an non-empty string/not-null element is found in the array. If you found one, it is a valid choice. But beware, if you removed all books, the randomizer would never stop running (because it finds only invalid choices and hence never returns). Here you can use an additional check condition: if the array only consists of empty strings/ null values, it is not required to run the randomizer.
Hope that helps...
I have two SQL tables. After grabbing both tables in ResultSets, I've stored them in String[][]s, ordered by a common id column. These tables should contain the same data, however one may have duplicates of the same row from the other. In order to check if every String[] in table A is present at least once in table B, I need to construct a somewhat efficient contains()-esque method for String[].
This is what I have so far, but am stumped (also not sure if there's a much more efficient solution). Give it the source table and target table. It takes each String[] in the source table and (should) go through each String[] in the target table and find an instance of the source String[] somewhere in the target String[][] by checking if there's at least one String[] that matches the original String[], element by element. Can anyone point me in the right direction and/or fill in the blanks? This isn't homework or any assignment, I'm refactoring some code and am having a major brain fart. Thanks!
public boolean targetContainsSource(String[][] s, String[][] t) {
boolean result = true;
//For each String[] in String[][] s
for (int i = 0; i < s.length; i++) {
//For each String[] in String[][] t
for (int j = 0; j < t.length; j++) {
//For each String in t's String[]
for (int k = 0; k < t[0].length; k++) {
if (!s[i][k].equals(t[j][k])) {
}
}
}
}
return result;
}
Your innermost loop could be removed by using Arrays.equals().
For each element of the first array, you should define a found boolean variable, that would only be set to true once the element is found in the second array. Once the second loop is finished, if this variable is still false, you have found an element of the first array that is not in the second, and you can return immediately.
And of course, as soon as this variable is set to true, you can break out of the second loop.
Essentially, you generally need to do the following:
use a strong hash function to take a hash of each row: this gives you a single integer (probably a long to be strong enough) or single string/byte array representing the entire row
then proceed as though you were comparing two "lists" of rows. At least one of these "lists" should actually be stored in a HashSet/HashMap, whose contains() method is efficient.
For the hash function you could use MD5 (e.g. you can use this code, but use "MD5" instead of "SHA-1"). You can use MessageDigest.compare() to compare to byte arrays representing hash codes.
If you only have a small number (say, a few tens of thousands) of rows, then you could use a 64-bit hash code-- this just has the advantage that each hash is stored in a long so they're a bit easier to shufty about and compare. But 64-bit hash codes are only strong enough for guaranteeing uniqueness of hashes of tens to hundreds of thousands of objects (=different rows in your case).
P.S. If you're prepared to store all of the data in memory, then you could also just use as the "hash" of each row all of the columns concetenated together into a single string. The trick is to make the check efficient to have one of the tables' row representations stored in a HashSet/HashMap.
Disclaimer: This is for a homework assignment.
I am currently working on an assignment where I need to implement an iterable interface in order to pass each array from a square two-dimensional array. This array is supposed to represent a grid of numbers (so I will be referring to them as such [row][col]). My problem is that I want to use the same next method to iterate through the rows and the columns. First, is this possible? Second, any suggestions/hints?
My next method currently looks like this:
public Data[] next(){
Data [] holder = new Data[ray.length];
for (int i = 0; i <ray.length; i++)
holder[i]=ray[counter][i];
counter++;
return holder;}
EDIT: I am aware of being able to switch counter and i in ray[counter][i], but I'm not sure how to have it do both if that's possible.
ray is the multidimensional array and count is an attribute of the Iterator method I've created (It's initialized to 0 and this is the only method that changes it). I know I cannot return the "column" of ray this way, so how would I go about having next call columns and rows?? Thanks for any of the help. I'll be standing by if you have further questions.
My problem is that I want to use the same next method to iterate through the rows and the columns. First, is this possible?
Yes it is possible, assuming you mean what I think you mean. (The phrase "iterate through the rows and the columns" is horribly ambiguous.)
Since this is a homework exercise here are a couple of hints:
You need two counters not one.
When you get to the end of one row you need to go to the start of the next row. (Obviously!) Think about what that means if you've got two counters.
This should be enough to get you on the right track.
I want a row by row iteration and a column by column iteration.
This is also a horribly ambiguous description, but I'm going to interpret it as meaning that sometimes you want to iterate left to right and top to bottom, and other times you want to iterate top to bottom and left to right.
That is also possible:
One possibility is to use an extra state variable to tell the iterator which direction you are iterating; i.e. row within column, or column within row.
Another possibility is to implement two distinct Iterator classes for the two directions.
The problem is that the iterator class is only supposed to have one counter and returns an single-dimension array.
You've (finally) told us unambiguously that the iterator is supposed to return an array. (A good dentist could pull out a tooth quicker than that!)
So here's a hint:
Returning the ith row is easy, but returning the jth column requires you to create a new array to hold the values in that column.
My advice is: transform the 2d array to a list and iterate.
When initialize the Iterator, transform the list. Then you could iterate the list easily.
Following is p-code, you could enrich the implementation in your homework. Hope it helps you!
class TwoDimeIterator implements Iterator<Date> {
List transformedList = new ArrayList();
int cursor = 0;
/** transform to a list row by row.
So you could define your Iterator order.**/
TwoDimeIterator(){
for(int i=0; i < ray.length; i++)
for(int j=0; j < ray[0].length; j++)
transformedList.add(ray[i][j]);
}
public Date next() {
return transformedList.get(cursor++);
}
public boolean hasNext() {
return cursor != transformedList.size();
}
//...
}