I'm making a store in java and I'm trying to add a new item to an array, but I can't figure out how to make it work. add.items(i); won't work because that's only for ArrayList, and a requirement for this task is that I have to use an array. The purpose of this function is it checks if there is an empty space in the array, which has a maximum size of 10, and it adds an item if it's not full.
public boolean addItem (Item i){
for (int i = 0; i < items.length; i++) {
if (items[i] == null) {
add.items(i);
return true;
}
return false;
}
}
Your code won't work because you are using duplicate variables i.
Try this instead:
public boolean addItem (Item item) {
// Rename loop variable
for (int x = 0; x < items.length; x++) {
if (items[x] == null) {
// Asign the incoming item to items array in case this position is empty
items[x] = item;
return true;
}
}
return false;
}
Related
I'm creating a resizeable Object Array. Below is my add function in which I pass through the object I want to add into my arraylist.
The function works, however if someone could explain this code
temp[theList.length] = toAdd;
I understand that it's adding the parameter argument to the end of the new Arraylist. But what's confusing me is the index that I pass into temp[]. Shouldn't I be including theList.length + 1 rather than just theList.length?
public boolean add(Object toAdd) {
if (toAdd != null) {
Object[] temp = new Object[theList.length + 1];
for (int i = 0; i < theList.length; i++) {
temp[i] = theList[i];
}
temp[theList.length] = toAdd;
theList = temp;
return true;
} else {
System.out.println("Invalid type");
return false;
}
}
Explanation for the add method:
Assume, the size of the theList is 10.
They have created an temp array which takes size as theList + 1, so size of temp is 11.
Now, objects are added to the temp except for the last element tem[10].
For adding the last element, you can use any of the 2 ways:
temp[theList.length] //temp[10]
Or
temp[temp.length-1] //temp[10]
They used the 1st way to add the toAdd object.
You could use a standard method Arrays.copyOf which immediately creates a copy of the input array with the new size (in this case, the length is increased):
import java.util.Arrays;
//...
public boolean add(Object toAdd) {
if (toAdd != null) {
int oldLength = theList.length;
theList = Arrays.copyOf(theList, oldLength + 1);
theList[oldLength] = toAdd;
return true;
} else {
System.out.println("Cannot add null object");
return false;
}
}
public static ArrayList<ArrayList<HSSFCell>> newTogether(ArrayList<ArrayList<HSSFCell>> sheetData) {
ArrayList<ArrayList<HSSFCell>> temporary = new ArrayList<ArrayList<HSSFCell>>();
for(int i = 0; i < sheetData.size(); i++) {
ArrayList<HSSFCell> list = sheetData.get(i);
if (list.get(3).getCellType() == Cell.CELL_TYPE_NUMERIC) {
if(Integer.parseInt(list.get(3).getStringCellValue()) > 100) {
temporary.add(list);
sheetData.remove(i);
i--;
}
}
}
for(int i = 0; i < sheetData.size(); i++) {
ArrayList<HSSFCell> list = sheetData.get(i);
temporary.add(list);
}
return temporary;
}
What I am trying to do with my code is have the 2D ArrayList take out any numbers greater than 100 and put them in the beginning of the ArrayList, while preserving the order of the remaining elements. However, this code just returns an ArrayList in the original order, and if I add a println to either if, I get nothing. Could someone point out what it is I'm doing wrong?
Have you tried putting a println in front of the first if to check what getStringCellValue() returns?
btw. since Collections.sort is guaranteed to be stable according to the API documentation, you could use that. Should be faster than your way of doing it.
That could look like this
private static boolean biggerThan100(ArrayList<HSSFCell> list) {
return list.get(3).getCellType() == Cell.CELL_TYPE_NUMERIC &&
(Integer.parseInt(list.get(3).getStringCellValue()) > 100);
}
public static ArrayList<ArrayList<HSSFCell>> newTogether(ArrayList<ArrayList<HSSFCell>> sheetData) {
ArrayList<ArrayList<HSSFCell>> temp = new ArrayList<>(sheetData);
Collections.sort(temp, new Comparator<ArrayList<HSSFCell>>() {
public int compare(ArrayList<HSSFCell> a, ArrayList<HSSFCell> b) {
if(biggerThan100(a) && !biggerThan100(b)) return -1;
else if(biggerThan100(b) && !biggerThan100(a)) return 1;
else return 0;
}
});
return temp;
}
Where is the possible memory leak in my code? There is also supposed to be a programming error too in one the methods as well, that might cause problems if I create a subclass of this class.
The add method basically just takes an index of where to add the item. For every item that occupies anything after the index in the current array, it just copies it over a spot over, and then places the item into index. I don't see what's wrong with it.
For the remove method, it does the same thing basically, except in reverse.
private static final int MAX_LIST = 3;
protected Object []items;
protected int numItems;
public MyArray()
{
items = new Object[MAX_LIST];
numItems = 0;
}
/*the programming error should be in this method*/
public void add(int index, Object item)
throws ListIndexOutOfBoundsException
{
if (numItems > items.length)
{
throw new ListException("ListException on add");
}
if (index >= 0 && index <= numItems)
{
for (int pos = numItems-1; pos >= index; pos--)
{
items[pos+1] = items[pos];
}
items[index] = item;
numItems++;
}
else
{
throw new ListIndexOutOfBoundsException(
"ListIndexOutOfBoundsException on add");
}
}
/*The memory leak should be in this method*/
public void remove(int index)
throws ListIndexOutOfBoundsException
{
if (index >= 0 && index < numItems)
{
for (int pos = index+1; pos < numItems; pos++)
{
items[pos-1] = items[pos];
}
numItems--;
}
else
{
throw new ListIndexOutOfBoundsException(
"ListIndexOutOfBoundsException on remove");
}
}
Make sure that unused items elements are set to null otherwise objects referenced from there cannot be garbage collected.
After the for loop shifting down the items add a line:
items[numItems-1] = null;
Creating an instance of an object (o) and adding it to an Arraylist (arrayList) works fine. However, the remove function doesn't work.
arrayList.add(o); // works
arrayList.remove(o); // does nothing
What am I missing?
ArrayList.remove() look like this:
public boolean remove(Object o) {
if (o == null) {
for (int index = 0; index < size; index++)
if (elementData[index] == null) {
fastRemove(index);
return true;
}
} else {
for (int index = 0; index < size; index++)
if (o.equals(elementData[index])) {
fastRemove(index);
return true;
}
}
return false;
}
So, if your Object has default equals(), then this cant work. All object are diffrent. Add equals() to your Object class.
So I have written a TransferHandler for my application (along the example from Oracle site) but when I am trying to move the data it is not moving. All it is doing is copying the data at index ( n-1 i.e if I am moving and item to n location) to index n. Could you please check what is wrong, though I have tried many options but none of them is working for me.
import javax.swing.TransferHandler;
import javax.swing.*;
import java.awt.datatransfer.*;
public class ListTransferHandler extends TransferHandler {
private int[] indices = null;
private int addIndex = -1; //Location where items were added
private int addCount = 0; //Number of items added.
public boolean canImport(TransferHandler.TransferSupport info) {
// Check for String flavor
if (!info.isDataFlavorSupported(DataFlavor.stringFlavor)) {
return false;
}
return true;
}
protected Transferable createTransferable(JComponent c) {
return new StringSelection(exportString(c));
}
public int getSourceActions(JComponent c) {
return TransferHandler.MOVE;
}
public boolean importData(TransferHandler.TransferSupport info) {
if (!info.isDrop()) {
return false;
}
JList list = (JList)info.getComponent();
DefaultListModel listModel = (DefaultListModel)list.getModel();
JList.DropLocation dl = (JList.DropLocation)info.getDropLocation();
int index = dl.getIndex();
boolean insert = dl.isInsert();
// Get the string that is being dropped.
Transferable t = info.getTransferable();
String data;
try {
data = (String)t.getTransferData(DataFlavor.stringFlavor);
}
catch (Exception e) { return false; }
// Perform the actual import.
if (insert) {
listModel.add(index, data);
} else {
listModel.set(index, data);
}
return true;
}
protected void exportDone(JComponent c, Transferable data, int action) {
cleanup(c, action == TransferHandler.MOVE);
}
//Bundle up the selected items in the list
//as a single string, for export.
protected String exportString(JComponent c) {
JList list = (JList)c;
indices = list.getSelectedIndices();
Object[] values = list.getSelectedValues();
StringBuffer buff = new StringBuffer();
for (int i = 0; i < values.length; i++) {
Object val = values[i];
buff.append(val == null ? "" : val.toString());
if (i != values.length - 1) {
buff.append("\n");
}
}
return buff.toString();
}
//Take the incoming string and wherever there is a
//newline, break it into a separate item in the list.
protected void importString(JComponent c, String str) {
JList target = (JList)c;
DefaultListModel listModel = (DefaultListModel)target.getModel();
int index = target.getSelectedIndex();
//Prevent the user from dropping data back on itself.
//For example, if the user is moving items #4,#5,#6 and #7 and
//attempts to insert the items after item #5, this would
//be problematic when removing the original items.
//So this is not allowed.
if (indices != null && index >= indices[0] - 1 &&
index <= indices[indices.length - 1]) {
indices = null;
return;
}
int max = listModel.getSize();
if (index < 0) {
index = max;
} else {
index++;
if (index > max) {
index = max;
}
}
addIndex = index;
String[] values = str.split("\n");
addCount = values.length;
for (int i = 0; i < values.length; i++) {
listModel.add(index++, values[i]);
}
}
//If the remove argument is true, the drop has been
//successful and it's time to remove the selected items
//from the list. If the remove argument is false, it
//was a Copy operation and the original list is left
//intact.
protected void cleanup(JComponent c, boolean remove) {
if (remove && indices != null) {
JList source = (JList)c;
DefaultListModel model = (DefaultListModel)source.getModel();
//If we are moving items around in the same list, we
//need to adjust the indices accordingly, since those
//after the insertion point have moved.
if (addCount > 0) {
for (int i = 0; i < indices.length; i++) {
if (indices[i] > addIndex) {
indices[i] += addCount;
}
}
}
for (int i = indices.length - 1; i >= 0; i--) {
model.remove(indices[i]);
}
}
indices = null;
addCount = 0;
addIndex = -1;
}
}
You need to "remove" the data from the source once the export has been completed successfully.
In order to do this, you need to override the TransferHandler.exportDone method.
protected void exportDone(JComponent source,
Transferable data,
int action)
Invoked after data has been exported. This method should remove the
data that was transferred if the action was MOVE.
This method is implemented to do nothing since MOVE is not a supported
action of this implementation (getSourceActions does not include
MOVE).
Basically, from there you need to check the action type and make sure the target component has accepted the MOVE and not simply COPY'ed it and remove the element from the source list.