While and for loops for adding to two dimensional array - java

I have an arrayList which contains Objects. Each object contains a number of strings. I am trying to take these strings and add them to a two dimensional array.
public void iterateRow(Row row)
{
int x = 0;
int y = size();
tableArray = new String[y][5];
while(x < y){
int z = 0;
for (String s: row.rowString()){
tableArray[x][z] = s;
z++;
}
x++;
}
}
Whenever i run and create a new instance for the row class the method should add the strings contained in Row to the array. However it duplicates the latest entry x times (where x is the total number of entries).
Here is the Row class for further reference:
public class Row
{
public String appNumber;
public String name;
public String date;
public String fileLoc;
public String country;
public String elementString;
public String results[];
public Row(String appNumber, String name, String date, String fileLoc, String country, Table table)
{
this.appNumber = appNumber;
this.name = name;
this.date = date;
this.fileLoc = fileLoc;
this.country = country;
table.addApplicant(this);
}
public String[] rowString()
{
String[] a = {appNumber, name, date, fileLoc, country};
return a;
}}
I think it is a silly logical error in the iterateRow() method but i can't seem to work out what. Any help would be appreciated.
Edit: After everybody's help i have removed the while loop. However it still seems to be duplicating the Row rather than moving onto the next?
public void iterateRow(Row row)
{ int x = 0;
int y = size();
tableArray = new String[y][row.rowString().length];
for(int i =0; i<y;i++){
int z = 0;
for (String s: row.rowString()){
tableArray[x][z] = s;
z++;
}x++;}
}

The problem looks like it is in the while loop. If size() returns 3, for example, then the while loop will execute with x=0,1,2 so you'll assign tableArray[0], then tableArray[1] and then tableArray[2].
Its hard to tell what the solution is as I can't understand why you've got the while loop in the code at all.

It looks like you want to iterate through each element of a List of Rows
Maybe you want to use a method similar to the following:
public void iterateRows(List<Row> rows) {
int cols = 5;
int row = 0, col = 0;
tableArray = new String[rows.size()][cols];
for(Row row : rows) {
col = 0;
for(String c : row.rowString()) {
tableArray[row][col] = c;
col++;
}
row++:
}
}
However, it would be good to implement your own error checking incase there are more than 5 columns...
EDIT
This is probably not the best design to use for your program, and I would recommend changing it so that when a new row is added, you don't have to iterate through each of the old rows as well.

Your iterateRow method re-creates tableArray each time it is called. Because of the while loop, your Row object gets replicated y times in the array.
I suspect that you want to create your array outside of the iterateRow method and not use a while loop (just the for loop) to populate the next slot in your array.

You are not taking care to size the two dimensional array relative to the size of the Row.
While this might not be the smoking gun, it would be far safer to do
tableArray = new String[y][row.rowString().length];
instead of
tableArray = new String[y][5];

I don't know if this is for practical purpose or how IterateRow() is called, but a logical way to get this working would be to declare the array first, add 2 argument in IterateRow(reference of the array and currentRow). Then, inside iterateRow you get rid of the while loop and you just loop for the string proprieties.

Related

sort array of objects java with different properties

I have an object array containing two fields per object.
I have to write a method that will sort my array by the first field.
I already have a method which extracts the first field from each object
I always get an error message when I call my method to sort.
Here is my code:
public static void trier(String[]code, String[]nom, int nbObj) {
for(int i = 0; i < nbObj-1; i++) {
int indMin = i;
for (int j = i+1; j < nbObj; j++)
if (code[j].compareTo(code[indMin]) < 0)
indMin = j;
if (indMin != i) {
// permutation :
String tempo = code[i];
code[i] = code[indMin];
code[indMin] = tempo;
// permutation :
String temp = nom[i];
nom[i] = nom[indMin];
nom[indMin] = temp;
}
}
}
and the call :
Classe.trier(tableau, tableau, nbObj);
I also tried Class.sort(array.getCode(), array.getName(), nbStudent);
But I still have compilation errors
thank you in advance for your help
First of all, you don't have to use 2 separate arrays to contain your data. You can put everything in a single array, but better way is to use Java Collections. Perfect choice is ArrayList. However, you still better combine two fields into a single object. You can do it like this:
public class MyObject {
String code;
String nom;
MyObject(String code, String nom) {
this.code = code;
this.nom = nom;
}
}
Now you have a class containing 2 fields. Your aim is to sort a collection of such objects by their second field (nom). You can do this easily since Java 8:
public static void sort1(ArrayList<MyObject> list) {
list.sort((obj1, obj2) -> obj1.nom.compareTo(obj2.nom));
}
Or
public static void sort2(ArrayList<MyObject> list) {
list.sort(Comparator.comparing(MyObject::getNom));
} // However for this you need to add method getNom to MyObject
Remember to put your objects in the collection properly.
For example:
MyObject a = new MyObject("abc", "abide");
MyObject b = new MyObject("cab", "whatever you want");
ArrayList<MyObject> list = new ArrayList<>();
list.add(a);
list.add(b);
trier(list);

java for loop does not update variable

public CarDealerShip() {
cars = new Car[80];
listSize=0;
}
public void addNewCar (String model, int year, int price, String color) {
m = model;
y = year;
p = price;
c = color;
cars [listSize] = new NewCar (m,y,p,c);
listSize++;
}
public void addUsedCar (String model, int year, int price, boolean rusty) {
m = model;
y = year;
p = price;
r = rusty;
cars [listSize] = new UsedCar(m,y,p,r);
listSize++;
}
public String printReport() {
String list="";
if (cars.length==listSize)
for (int i =0; i <= listSize; i++)
list+=cars[i].toString()+"\n";
return list;
}
In the method printReport, the for loop is suppose to update the variable list but does nothing at all. It been a while since i use Java again so any help is appreciated.
Since 0 <= 0, the for loop will iterate once even if listSize==0 (even if cars[0] is not defined).
So if printReport "does nothing at all" (including throwing an exception), the most likely cause is that the expression in the if statement evaluates to false.
This might happen if you haven't added 80 cars to cars when you try calling printReport.
When you create an object of the class CarDealerShip, the variable listSize gets a value of 0 while the 'cars' array is 80 elements long.
So basically this IF fails:
if (cars.length==listSize).
Hence, the for loop is never entered.
This is all that can be said from the code you provided.
Remove this line :
if (cars.length==listSize)
Because cars is a array whose length is 80 and the variable listSize gets a value of 0 at the time of creating this class . So for loop is not executed .

Two Dimension Arrays Re-Write

Hey this code works just fine, but it is difficult to read. I am looking for a way to do this better.
public void printArray(String[/*row*/][/*column*/] twoDiArray) {
if (twoDiArray.length == 2) {
for (int i = 0; i < twoDiArray[0].length; i++) {
//prints attribute name and value
attributeNameAndValue(twoDiArray[0][i],twoDiArray[1][i]);
}
} else {
System.out.println("Does not fit format standards :: 2d array :: two rows max :: first row name :: second row value");
}
}
The part I seriously dislike is the length calls in the if statement and the for loop. Is there a better way to do this or is it just a sloppy section of java language.
You have pairs name-value, if your names are unique, you should use Map<String, Integer> instead. Otherwise, create your own class called e.g. Attribute and use List<Attribute>:
public class Attribute {
private final String name;
private final int value;
public Attribute(String name, int value) {
this.name = name;
this.value = value;
}
public String getName() {
return name;
}
public int getValue() {
return value;
}
}
This gives you compile-time safety for the second dimension. Your code would look like this:
public void printArray(List<Attribute> attributes) {
for (Attribute attribute : attributes) {
attributeNameAndValue(attribute.getName(), attribute.getValue());
}
}
You can use new variable to save the value of twoDiArray.length and use new var below.
This can certainly be cleaned up a little bit. A different approach as other people have mentioned would have much neater code. It's a little bizarre that you have row and column like that. Reversing the order would also make things cleaner:
public void printArray(String[/*row*/][/*column*/] twoDiArray){
if(twoDiArray.length!=2){
System.out.println("Does not fit format standards :: 2d array :: two rows max :: first row name :: second row value");
return;
}
int len = twoDiArray[0].length;
for(int i = 0; i<len.length; i++){
//prints attribute name then value
attributeNameAndValue(twoDiArray[0][i],twoDiArray[1][i]);
}
}
Another thing would be to change attributeNameAndValue to accept i and twoDiArray for a "neater" call.
another way to check array
public void printArray(String[/*row*/][/*column*/] twoDiArray){
assert twoDiArray.length == 2;
for(int i=0; i<twoDiArray[0].length; i++){
attributeNameAndValue(kvp[i][0], kvp[i][1]);
}
}
To improve the code readability apply the java code conventions (http://www.oracle.com/technetwork/java/codeconvtoc-136057.html).
Introduce variables rows and columns (for the number of rows and number of columns)
public void printArray(String[/*row*/][/*column*/] twoDiArray) {
int rows = twoDiArray.length;
if (rows != 2) {
System.out.println("Does not fit format standards :: 2d array :: two rows max :: first row name :: second row value");
return;
}
int columns = twoDiArray[0].length;
for (int column = 0; column < columns; column++) {
//prints attribute name then value
attributeNameAndValue(twoDiArray[0][column], twoDiArray[1][column]);
}
}

Using a data structure to solve this in O(n)

we have sequence of 4 characters (A,B,C and D)that map to numbers form 1 to n.
we define components to be:
Component(k) :
A {cell[k]}
if Color(left_k) = Color(k)
then
A <-- A U Component(left_k)
if Color(right_k) = Color(k)
then
A <-- A U Component(left_k)
return A
there is 3 types of operations(the numbers in list indicate the input):
by giving index it should remove the component in that index(the numbers mapping to characters are fixed)
example : AABBBDA is the string. if index is 3 it should return AADA
by giving index it should rotate the string based on the component on that index(the numbers mapping to characters are fixed)
example : AABBBDA is the string. if index is 3 it should return DABBBAA
it should print the string.
inputs are like:
1 2 --> first operation with index=2
2 3 --> second operation with index=3
3 --> third operation
It's an assignment, happy to get help.
this is what i've tried so far:
public static void main(String[] args)
{
int numberOfOps;
String[] print = new String[30];
List list = new List();
Scanner input = new Scanner(System.in);
int count = input.nextInt();
String colors = new String();
colors = input.next();
for(int i = 0; i < count; i++)
{
list.add(colors.charAt(i));
}
numberOfOps = input.nextInt();
list.printElement();
for (int i = 0; i < numberOfOps; i++)
{
int op = input.nextInt();
if(op == 1)
{
int index = input.nextInt();
char c = list.item[index];
int temp = index;
int prevIndex = index;
int nexIndex = index;
if(index != 0)
{
while (list.item[--index] == c)
{
prevIndex--;
}
while (list.item[++temp] == c)
{
nexIndex++;
}
list.setNext(prevIndex-1, nexIndex+1);
}
else
{
while (list.item[++temp] == c)
{
nexIndex++;
}
list.setNext(prevIndex, nexIndex+1);
}
}
if(op == 2)
{
int index = input.nextInt();
}
if(op == 3)
{
print[i] = list.printElement();
}
}
}
here is my List class:
public class List {
// reference to linked list of items
public static final int MAX_LIST = 20;
public static final int NULL = -1;
public char item[] = new char[MAX_LIST]; // data
public int avail;
public int next[] = new int[MAX_LIST]; // pointer to next item
private int numItems; // number of items in list
public List()
{
int index;
for (index = 0; index < MAX_LIST-1; index++)
next[index] = index + 1;
next[MAX_LIST-1] = NULL;
numItems = 0;
avail = 0;
} // end default constructor
public void add(char e)
{
item[avail] = e;
avail = next[avail];
numItems++;
}
public String printElement()
{
String temp = null;
int index = 0;
while(index<avail)
{
temp += item[index];
System.out.println(item[index]);
index = next[index];
}
return temp;
}
public int size()
{
return numItems;
}
public void setNext(int i, int value)
{
next[i] = value;
}
}
if you test it you'll get, it has lots of problems, such as, I have no idea to do the rotate operation, and it has problem with connecting two components when the middle component has been removed.
This is a difficult question to answer, because the requirements are not properly stated.
For example the first bunch of pseudo-code does not make it clear whether A is a set, a multi-set or a list. The notation (use of curly brackets, and U (union?)) seems to say set ... but the output seems to be a list. Or maybe it is supposed to be a schema for a data structure??
And even the inputs are not clearly described.
But putting that on one side, there is still room for some (hopefully) helpful advice.
Make sure that >>you<< understand the requirements. (I imagine that the real requirements for the assignment are better stated than this, and the details have been "lost in translation".)
I would actually use an array list (or a StringBuilder) rather than a linked list for this. (But a properly implemented linked list ... implementing the List API ... would work.)
But whatever data structure you chose, there is no point in implementing it from scratch ... unless you are specifically required to do that. There are perfectly good list classes in the Java standard libraries. You should reuse them ... rather than attempting to reinvent the wheel (and doing a bad job).
If you are required to implement your own data structure type, then your current attempt is a mess. It looks like a hybrid between an array list and a linked list ... and doesn't succeed in being either. (For example, a decent array list implementation does not need a MAX_LIST, and doesn't have next pointers / indexes. And a linked list does not have any arrays inside it.)

Why do I keep on getting an ArrayIndexOutofBoundsException?

I am trying to program a program that mimics the actions of a vending machine for my CS class. I have a double array stock that represents the the number of items at a particular "slot" [my vending machine is weird and is kinda like one long vending machine with 1 column of different items]. Here is my code so far:
public class VendingMachine
{
// define fields here
public static double itemPrice[];
public static String[] itemName;
public static int stock[][];
public static int maxPerSlot;
public static double cashAmmount;
public VendingMachine(int numslots, int maxperslot, double cash)
{
final int numSlots = numslots;
maxPerSlot = maxperslot;
cashAmmount = cash;
stock = new int[numSlots][0];
itemPrice = new double[numSlots];
itemName = new String[numSlots];
// complete this method
}
public void setProduct(int slot, String product, double price)
{ int Slot = slot;
itemPrice[slot] = price;
itemName[slot] = product;
stock[Slot][0] = 0;
//
}
public void restockProduct(String product, int quantity)
{
String Product = product;
int currentCapacity = quantity - maxPerSlot;
for(int i = 0; i < stock.length; i++){
if (itemName[i]==Product){
for(;quantity <= maxPerSlot && currentCapacity != 0; quantity--)
stock[i][0] += 1;
}
}
//Put # of products in slot that holds it and if that slot is full put the rest in the next
//availble slot that holds that product, if all full return error.
}
public double getCashOnHand()
{
return cashAmmount; // replace this line with your code
}
public int getQuantity(int slot)
{
return stock[slot][1]; // replace this line with your code
}
public int getQuantity(String product)
{ int total = 0;
for (int i = 0; i<itemName.length;i++){
if (product == itemName[i]){
total += stock[i][1];
}
}
return total;
}
public boolean buyItem(int slot)
{ int snum = slot;
if (stock[snum][1] != 0){
stock[snum][1]--;
return true;
} else {
return false;} // replace this line with your code
}
}
Every time I runException in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at VendingMachine.setProduct(VendingMachine.java:27)
at vmd.main(vmd.java:9) this code though I get this error message:
Can someone here please explain to me why I continue to get this error? I mean the logic seems quite correct .
Your problem's here:
stock = new int[numSlots][0];
This defines an array of numSlot arrays with a length of 0 each.
when you initialize stock in the constructor do this instead:
stock = new int[numSlots][1];
using 0 instead of 1 initializes an array of length 0!
You allocate zero elements in the second dimension of stock,
stock = new int[numSlots][0];
so you get that exception when you try to access the element at index zero.
stock[Slot][0] = 0;
This line
stock = new int[numSlots][0]; // <-- A length of zero? You want a one there.
Should be
stock = new int[numSlots][1]; // <-- like so. Or, if you really don't
// want to change your other code make it a 2.
// But you'll leave memory unused, and you really should change it.
Everywhere else (where you have code like this) -
stock[slot][1] // <-- stock[INDEX][1] <--- should be 0.
Like this
stock[slot][0] // <-- all of the other accesses.
Because this line:
stock = new int[numSlots][0];
allocates stock to be an array of arrays, and each of those arrays has length 0. So you can't assign anything into those arrays (they don't have any elements to assign). So when you do this:
stock[Slot][0] = 0;
you will get an ArrayIndexOutOfBounds. Remember that in Java, indexes start at 0, so if you want an array where the indexes go from 0 to N, you have to allocate the array with size N+1.

Categories

Resources