Issues with an Array in an ArrayList, Java - java

I created a multidimensional array called current_map.
I am trying to access current_map:
current_map[0][1]
However I receive the error:
error: array required, but String found
Here is my code for your viewing pleasure
import java.util.*;
import java.util.Map.Entry;
import java.util.ArrayList;
public class TestApp {
private ArrayList<String[]> current_map = new ArrayList<String[]>();
public TestApp() {
current_map.add(new String[] { "0","0","0" });
current_map.add(new String[] { "0","Q","0" });
current_map.add(new String[] { "0","0","0" });
}
public String getValue(int X,int Y){
String[] obj_map = current_map.toArray(new String[current_map.size()]);
return obj_map[X][Y]; // for example, getValue(2,2), should give "Q"
}
}
How can I stop this issue?

You can do something like this:
import java.util.*;
import java.util.Map.Entry;
import java.util.ArrayList;
public class TestApp {
private ArrayList<String[]> current_map = new ArrayList<String[]>();
public TestApp() {
current_map.add(new String[] { "0","0","0" });
current_map.add(new String[] { "0","Q","0" });
current_map.add(new String[] { "0","0","0" });
}
public String getValue(int X,int Y){
return current_map.get(Y)[X]; // for example, getValue(2,2), should give "Q"
}
public static void main(String[] args) {
TestApp ta = new TestApp();
System.out.println(ta.getValue(1, 1));
}
}
Note that in Java array indexes are 0-based, so 2nd row, 2nd column is represented with (1, 1), not (2, 2).
Hope this helps.

Unless there's compelling reason to do a full copy on every get command, you should use your existing structure.
public String getValue(int X, int Y)
{
return current_map.get(X)[Y];
}

You have said obj_map is a String[], but in the very next line you treat it as a 2D array.

What you have is not really a true multi-dimension representation as the way you access different dimensions is not consistent. Its semantics but to call it a true multi-dimensional (including symantics) you need something like this (Please refer this for the source of this code. I am not the owner of this code.)
import java.util.ArrayList;
public class ArrayList2d<Type>
{
ArrayList<ArrayList<Type>> array;
public ArrayList2d()
{
array = new ArrayList<ArrayList<Type>>();
}
/**
* ensures a minimum capacity of num rows. Note that this does not guarantee
* that there are that many rows.
*
* #param num
*/
public void ensureCapacity(int num)
{
array.ensureCapacity(num);
}
/**
* Ensures that the given row has at least the given capacity. Note that
* this method will also ensure that getNumRows() >= row
*
* #param row
* #param num
*/
public void ensureCapacity(int row, int num)
{
ensureCapacity(row);
while (row < getNumRows())
{
array.add(new ArrayList<Type>());
}
array.get(row).ensureCapacity(num);
}
/**
* Adds an item at the end of the specified row. This will guarantee that at least row rows exist.
*/
public void add(Type data, int row)
{
ensureCapacity(row);
while(row >= getNumRows())
{
array.add(new ArrayList<Type>());
}
array.get(row).add(data);
}
public Type get(int row, int col)
{
return array.get(row).get(col);
}
public void set(int row, int col, Type data)
{
array.get(row).set(col,data);
}
public void remove(int row, int col)
{
array.get(row).remove(col);
}
public boolean contains(Type data)
{
for (int i = 0; i < array.size(); i++)
{
if (array.get(i).contains(data))
{
return true;
}
}
return false;
}
public int getNumRows()
{
return array.size();
}
public int getNumCols(int row)
{
return array.get(row).size();
}
}

Related

Java heap space exception when trying to fill a list

I'm writing a program in java and i need to make a list whose nodes are another list . My code for the nodes of the sub list is this :
public class Page {
private String word;
private int num;
public String getWord() {
return word;
}
public void setWord(String word) {
this.word = word;
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
public Page(String word, int num) {
this.word = word;
this.num = num;
}
}
My code for the nodes of my main list is :
import java.util.ArrayList;
public class IndPage {
private ArrayList<Page> Eggrafi;
//private ArrayList<Page> Eggrafi = new ArrayList<Page>();
public IndPage(String name, int bytes) {
Eggrafi = new ArrayList<Page>();
Eggrafi.add(new Page(name, bytes));
}
public ArrayList<Page> getEggrafi() {
return Eggrafi;
}
public void setEggrafi(ArrayList<Page> eggrafi) {
Eggrafi = eggrafi;
}
}
When i use in my main the following code to fill my list i get a java heap space exception:
if(Index.size()!=0){
for(int j=0;j<Index.size();j++){
for(int y=0;y<Index.get(j).getEggrafi().size();y++){
if((Index.get(j).getEggrafi().get(y).getWord()).equals(tokens[i-1])){
Index.get(j).getEggrafi().add(new Page(fileName[k],byte_count));
}
else{
Index.add(new IndPage(fileName[k],byte_count));
}
}
}
}
else{
Index.add(new IndPage(fileName[k],byte_count));
}
Also my main list is declared this way :
List<IndPage> Index = new ArrayList<IndPage>();
I've tried many things but still getting the java heap space exception .
Your issue is in your for loop:
for(int j=0;j<Index.size();j++){
for(int y=0;y<Index.get(j).getEggrafi().size();y++){
if((Index.get(j).getEggrafi().get(y).getWord()).equals(tokens[i-1])){
Index.get(j).getEggrafi().add(new Page(fileName[k],byte_count));
}
else{
Index.add(new IndPage(fileName[k],byte_count));
}
}
}
Your for loops are doing a check against the lists .size() function you are adding new items to those lists, so the .size() will always be at least 1 more than either the j or y index variables and the loops will never terminate. That eventually is running you out of heap space. The Index.size() and Index.get(j).getEggrafi().size() values are recalculated each time by the for loop, they are not cached.
I think you code is allocating a new list for every insert.
import java.util.List;
import java.util.ArrayList;
public class IndPage {
private List<Page> Eggrafi = new ArrayList<Page>();
public IndPage(final String name, final int bytes) {
Eggrafi.add(new Page(name, bytes));
}
public List<Page> getEggrafi() {
return Eggrafi;
}
public void setEggrafi(final List<Page> eggrafi) {
Eggrafi = eggrafi;
}
}
The code for the loops can be improved by using Java 5 style collection loops ie:
for (final Page page : Eggrafi) {
...
}

Java method decrementing values but not reassigning

Okay I got two classes my main which is Process and a class called Scheduler
Aim: basically create an array of processes, along with their time remaining. Call the schedule class which essentially removes the number 1 from the timeRemaining
Here is the main method:
public static void main(String[] args) {
// TODO code application logic here
Random rn = new Random();
Scheduler scheduler = new Scheduler();
for(int i = 1; i<=5; i++){
double rand = rn.nextInt(10);
Process process = new Process(i,rand);
scheduler.addObj(process); // adds the object to the array
}
scheduler.printQueue(scheduler.getList());
System.out.println("");
scheduler.sortQueue(scheduler.getList());
scheduler.printQueue(scheduler.getList());
for(int i =0; i <10; i++){
System.out.println("");
scheduler.scheduleNext(scheduler.getList());
scheduler.printQueue(scheduler.getList());
System.out.println("");
}
}
This is creating 5 processes which are stored in an array of objects. I then sort the array by descending order of the time remaining. This works perfectly fine.
The problem is the loop which is from 0 to 10. What i'm trying to make it do is call the method scheduleNext() which chooses which takes the array and then chooses which value to send the schedule method.
This is the scheduleNext() method:
public void scheduleNext(ArrayList<Process> list){
Process firstElement = list.get(0);
if (firstElement.schedule(firstElement.getTimeRemaining()) == true){
list.remove(0);
}
else{
Collections.rotate(list,-1);
}
}
And here is the schedule method :
public boolean schedule(double timeRemaining){
if(timeRemaining < 1){
this.timeRemaining = 0;
return true;
}
else{
this.timeRemaining = timeRemaining -1;
return false;
}
}
I've debugged it through many times, it decrements the timeRemaining and moves it to the bottom of the array. But when I print it out, it just prints out the normal value... Am I reassigning them correct?
Here's the entire code (Process Class)
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package process;
import java.util.Random;
/**
*
* #author Luke
*/
public class Process implements Comparable<Process> {
/**
* #param args the command line arguments
*/
private int processId;
private double timeRequired;
private double timeRemaining;
public Process(int processId, double timeRequired) {
this.processId = processId;
this.timeRequired = timeRequired;
this.timeRemaining = timeRequired;
}
public double getTimeRemaining() {
return timeRemaining;
}
public static void main(String[] args) {
// TODO code application logic here
Random rn = new Random();
Scheduler scheduler = new Scheduler();
for(int i = 1; i<=5; i++){
double rand = rn.nextInt(10);
Process process = new Process(i,rand);
scheduler.addObj(process);
}
scheduler.printQueue(scheduler.getList());
System.out.println("");
scheduler.sortQueue(scheduler.getList());
scheduler.printQueue(scheduler.getList());
for(int i =0; i <10; i++){
System.out.println("");
scheduler.scheduleNext(scheduler.getList());
scheduler.printQueue(scheduler.getList());
System.out.println("");
}
}
public void setProcessId(int processId) {
this.processId = processId;
}
public void setTimeRequired(double timeRequired) {
this.timeRequired = timeRequired;
}
public int getProcessId() {
return processId;
}
public double getTimeRequired() {
return timeRequired;
}
#Override
public int compareTo(Process o) {
if (this.timeRequired < o.timeRequired){
return -1;
}else if (this.timeRequired > o.timeRequired){
return 1;
}else{
return 0;
}
}
public boolean schedule(double timeRemaining){
if(timeRemaining < 1){
this.timeRemaining = 0;
return true;
}
else{
this.timeRemaining = timeRemaining -1;
return false;
}
}
#Override
public String toString() {
return "Process{" + "processId=" + processId + ", timeRequired=" + timeRequired + '}';
}
}
(Scheduler Class)
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package process;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
/**
*
* #author Luke
*/
public class Scheduler {
ArrayList<Process> list = new ArrayList<>();
public ArrayList<Process> getList() {
return list;
}
public void addObj(Process p){
list.add(p);
}
public void sortQueue(ArrayList<Process> list){
Collections.sort(list);
}
public void printQueue(ArrayList<Process> list){
for(Process i: list){
System.out.println(i);
}
}
public void scheduleNext(ArrayList<Process> list){
Process firstElement = list.get(0);
if (firstElement.schedule(firstElement.getTimeRemaining()) == true){
list.remove(0);
}
else{
Collections.rotate(list,-1);
}
}
}
Well, the code works fine. You must have mistaken timeRequired, which is printed, for timeRemaining, which is decreased.

getting a class having the same generic type of another class

This is my first question here, so thanks to everybody who make this forum lives.
I want my Image2D class to have the same generic type of my Point2D class.
Image2D.java :
package utilities;
import ij.ImagePlus;
import utilities.Point2D;
public class Image2D<T> {
ArrayList<Point2D<T>> original = new ArrayList<Point2D<T>>();
public Image2D(ImagePlus imp) {
// imp.getProcessor().getIntArray() returns a int[][]
this.original = matrixToImage2D(imp.getProcessor().getIntArray());
}
private static <T> ArrayList<Point2D<T>> matrixToImage2D(T[][] matrix) {
ArrayList<Point2D<T>> img = new ArrayList<Point2D<T>>();
for (int row=0; row<matrix.length; row++) {
for (int col=0; col<matrix[row].length; col++) {
img.add(new Point2D(col, row, matrix[row][col]));
}
}
return img;
}
}
Point2D.java:
package utilities;
public class Point2D<T> {
public int x;
public int y;
public T value;
public Point2D(int col, int row, T value) {
this.x = col;
this.y = row;
this.value = value;
}
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public T getValue() {
return this.value;
}
}
I must not use the good concept to do that, I just put the code to illustrate my idea.
Please can anyone tell me the java concepts I have to use ?
Thanks.
I suspect you already know where the problem is - you've added a comment summarising it.
// imp.getProcessor().getIntArray() returns a int[][]
The matrixToImage method needs a T[][] but you are giving it an int[][] which will not work.
You must either make ImagePlus take a generic parameter (ImagePlus<T>) and then make getIntArray return a T[][] or you must make matrixToImage2D take an int[][] as a parameter.
One other alternative would be to use T extends Number and make adapter methods that translate between int[][] and T[][].

Create a Dictionary using Array of Object

I have a problem with this code. My purpose is to create a Dictionary that counts the frequency of a word in a text, using an Array of Objects (I can't use Hash Map or something else). I created a class Pair that contains the couple (word,count).
public class Pair
{ public String word;
public int count;
public Pair(String word,int count)
{this.word=word;
this.count=count;
}
public String getWord()
{return word;}
public int getCount()
{return count;}
public void addCount()
{count++;}
public String toString()
{ return getWord()+" "+getCount();}
}
And the class Dict that creates an Array of object using the Pair class
public class Dict
{ private Pair [] a;
private int inputSize;
public Dict()
{a=new Pair[10];
inputSize=0;
}
public void insert(Pair x)
{ if(a.length==inputSize)
{ Pair newA []=new Pair [2*inputSize];
for(int i=0;i<inputSize;i++)
{ newA[i]=a[i];
}
a=newA;
}
for(int i=0;i<inputSize;i++) // i check if x is already in the array if i find it i replace it otherwise i add it in the array
{ if(a[i].getWord().equals(x.getWord()))
{a[i]=x;
}
}
a[inputSize++]=x;
}
public Pair find(Pair x) // if i don't find x return null
{ for(int i=0;i<inputSize;i++)
{ if(a[i].getWord().equals(x.getWord()))
{return a[i];}
}
return null;
}
public String toString()
{String s="";
for(int i=0;i<inputSize;i++)
{ s=s+a[i].toString()+'\n';
}
return s;
}
}
After I created the test class with the main method
import java.util.*;
import java.io.*;
public class MyDict
{public static void main(String [] args)
{ Dict d=new Dict();
Scanner c=new Scanner(System.in);
while(c.hasNext())
{String s=c.next();
Pair p=new Pair(s,1); // create a new pair
Pair previous=d.find(p);
if(previous!=null) //if the pair is already in the stack i add 1 to the counter otherwise i insert it in the array
{p.count++;}
else
{d.insert(p);}
s="";
}
System.out.println(d);
}
}
But it doesn't work, in particular the variable "count" doesn't grow.
For example, if I write "how how are are you you " I get:
how 1
are 1
you 1
Can anyone help me please?
Change p.count++ to previous.count++.
Otherwise you never change the count of the existing Pairs.
Pair p=new Pair(s,1);
Pair previous=d.find(p);
if(previous!=null) {
previous.count++;
} else {
d.insert(p);
}

Use String list as source of Combo Box

I wanted to use a String list as a source of various options in jComboBox in Java. Can you tell which method to use
Thanks
See Below for my answer... take into account this is untested and merely an example.
You need to create a custom implmentation of ComboBoxModel like Chandru said,
Then set the ComboBoxModel on your JComboBox using the setModel() method and add elements using ((CustomComboBoxModel<String>)jComboBox.getModel()).add(listOfThings);
Something like this:
import java.util.List;
import javax.swing.ComboBoxModel;
/**
* Custom Implementation of {#code ComboBoxModel} to allow adding a list of
* elements to the list.
*/
public interface CustomComboBoxModel<T> extends ComboBoxModel {
void add(List<T> elementsToAdd);
List<T> getElements();
}
and then implement the interface using something like this:
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractListModel;
/**
* Default Implementation of CustomComboBoxModel - untested.
*/
public class DefaultCustomComboBoxModel<T> extends AbstractListModel implements CustomComboBoxModel<T> {
List<T> objects;
T selectedObject;
/**
* Constructs an empty DefaultCustomComboBoxModel object.
*/
public DefaultCustomComboBoxModel() {
objects = new ArrayList<T>();
}
/**
* Constructs a DefaultCustomComboBoxModel object initialized with
* an array of objects.
*
* #param items an array of Object objects
*/
public DefaultCustomComboBoxModel(final T items[]) {
objects = new ArrayList<T>();
int i, c;
for (i = 0, c = items.length; i < c; i++) {
objects.add(items[i]);
}
if (getSize() > 0) {
selectedObject = objects.get(0);
}
}
// implements javax.swing.ComboBoxModel
/**
* Set the value of the selected item. The selected item may be null.
* Make sure {#code anObject} is an instance of T otherwise a
* ClassCastException will be thrown.
* <p>
* #param anObject The combo box value or null for no selection.
*/
#Override
public void setSelectedItem(Object anObject) {
if ((selectedObject != null && !selectedObject.equals(anObject))
|| selectedObject == null && anObject != null) {
selectedObject = (T) anObject;
fireContentsChanged(this, -1, -1);
}
}
// implements javax.swing.ComboBoxModel
#Override
public T getSelectedItem() {
return selectedObject;
}
// implements javax.swing.ListModel
#Override
public int getSize() {
return objects.size();
}
// implements javax.swing.ListModel
#Override
public T getElementAt(int index) {
if (index >= 0 && index < objects.size()) {
return objects.get(index);
} else {
return null;
}
}
/**
* Returns the index-position of the specified object in the list.
*
* #param anObject
* #return an int representing the index position, where 0 is
* the first position
*/
public int getIndexOf(T anObject) {
return objects.indexOf(anObject);
}
// implements javax.swing.MutableComboBoxModel
public void addElement(T anObject) {
objects.add(anObject);
fireIntervalAdded(this, objects.size() - 1, objects.size() - 1);
if (objects.size() == 1 && selectedObject == null && anObject != null) {
setSelectedItem(anObject);
}
}
// implements javax.swing.MutableComboBoxModel
public void insertElementAt(T anObject, int index) {
objects.add(index, anObject);
fireIntervalAdded(this, index, index);
}
// implements javax.swing.MutableComboBoxModel
public void removeElementAt(int index) {
if (getElementAt(index) == selectedObject) {
if (index == 0) {
setSelectedItem(getSize() == 1 ? null : getElementAt(index + 1));
} else {
setSelectedItem(getElementAt(index - 1));
}
}
objects.remove(index);
fireIntervalRemoved(this, index, index);
}
// implements javax.swing.MutableComboBoxModel
public void removeElement(T anObject) {
int index = objects.indexOf(anObject);
if (index != -1) {
removeElementAt(index);
}
}
/**
* Empties the list.
*/
public void removeAllElements() {
if (objects.size() > 0) {
int firstIndex = 0;
int lastIndex = objects.size() - 1;
objects.clear();
selectedObject = null;
fireIntervalRemoved(this, firstIndex, lastIndex);
} else {
selectedObject = null;
}
}
#Override
public void add(List<T> elementsToAdd) {
objects.addAll(elementsToAdd);
fireContentsChanged(this, -1, -1);
}
#Override
public List<T> getElements() {
return objects;
}
}
Extend DefaultComboboxModel and create a method which takes a Collection and sets the items from that collection. Set this custom model as your combobox's model using setModel().
Here you have code which creates combo box from array of Strings, all you need to do is transform your list to an array.
String petStrings = ...;
//Create the combo box, select item at index 4.
//Indices start at 0, so 4 specifies the pig.
JComboBox petList = new JComboBox(petStrings.toArray());
The easiest way is:
comboBox.setModel(new DefaultComboBoxModel(list.toArray()));
I know it's an old post, but I wanted to make a small addition to edwardsmatt's DefaultCustomComboBoxModel. Don't forget to add this constructor:
public DefaultCustomComboBoxModel(List<T> list) {
objects = list;
if (getSize() > 0) {
selectedObject = objects.get(0);
}
}
so that the model can also be initialized with a list, e.g.
myCombo.setModel(new DefaultCustomComboBoxModel(myList));
If you use ((CustomComboBoxModel)myCombo.getModel()).add(myList) you'll need to explicitly set the selected item.
You can also do it like this:
DefaultTableModel modelTabele = (DefaultTableModel) tblOsobe.getModel();
modelTabele.addColumn("Ime");
modelTabele.addColumn("Prezime");
modelTabele.addColumn("Datum Rodjenja");
for (Osoba osoba : Liste.osobe) {
System.out.println("" + osoba);
Object[] podaci = new Object[3];
podaci[0] = osoba.getIme();
podaci[1] = osoba.getPrezime();
podaci[2] = osoba.getDatumRodjenja();
modelTabele.addRow(podaci);
}
This model has 3 columns and as many rows as there are in Liste.osobe list of strings.

Categories