Adding items into Inventory confusion - java

The Inventory consists of two arrays, one an array of objects[10] and one an array of ints[10]. The array of objects is to identify an item, and the array of ints is supposed to keep track of how many you have. For some reason the code is producing all kinds of errors. Not really sure what to do!
public void additem(Object newItem) {
if (itemsInInventory == 0) {
invent[0] = newItem;
inventItemAmount[0]++;
itemsInInventory++;
}else if (itemsInInventory > 0) {
for (int i = 0; i < itemsInInventory; i++) {
if (invent[i].getItemNum() == newItem.getItemNum()) {
inventItemAmount[i]++;
} else {
invent[itemsInInventory] = newItem;
inventItemAmount[itemsInInventory]++;
itemsInInventory++;
}
}
}
}
Complete code can be found here: https://github.com/YungSheep/HitsujiStories

I see in your GitHub code that your inventory is limited to 10 ; and your if-else condition doesn't hold any case for itemsInInventory > 10, that will first give you an idea of where your NPE comes from. It might be better for you to change your current else if condition to something like "a > 0 && a <= max" then add a case when it's higher than your max capacity.
EDIT : Also, I'm pretty sure I know why you get messed up amounts for each type of item : if you imagine the if-else statement inside a loop, the item slot [0] would only be accessible once, when the player has an empty inventory. That means I can't add up any further in the slot [0] if I picked an item and set itemsInInventory to another number than 0 ! You might have to rebuild your if-else contents.
SECOND EDIT : In case you find it messy to code, I suggest you to make an InventorySlot class :
public class InventorySlot {
private Object object;
private int amount;
// CONSTRUCTOR (assuming you don't instanciate filled slots)
public InventorySlot() {
this.setObject(null);
this.setAmount(0);
}
// GETTERS AND SETTERS
public Object getObject() {
return this.object;
}
public int getAmount() {
return this.amount;
}
public void setObject(final Object object) {
this.object = object;
}
public void setAmount(final int amount) {
this.amount = amount;
}
// METHOD THAT ADDS NEW ITEM IF MATCHES. RETURNS BOOLEAN TO TELL IF SUCCEEDED
public bool addIfMatches(final Object object) {
if (this.getObject.getItemNum() == object.getItemNum()) {
this.setAmount(this.getAmount++);
return true;
} else {
return false;
}
}
// AND OTHER USEFUL METHODS...
}
Hope this helps you, happy coding !

Related

Removing specific element from ArrayList

I need help with removing just added element from the arrayList.
I have a private static ArrayList<Position> positions = new ArrayList<>() to which I'm adding objects of the class Position with parameters name, quantity, and price.
Than I have a method adding objects to the list, and in case if the same product is added for the second time, it is supposed to add the quantity to the first object of that name and remove that second one.
So far I have this method:
public void addPosition(Position p) {
for (Position poz: positions) {
if (poz.getname().equals(p.getname())) {
poz.setquantity(poz.getquantity() + p.getquantity());
}
} positions.add(p);
}
Adding quantities works just fine, but I've got problem with removing the element with recurring name.
Please help.
You shouldn't add duplicate items and then remove them. Just declare a method which handles adding items correctly; that is, it adds the item if it does not exist, and it updates the quantity if it does exist.
It should look like this:
public void addPosition(Position addition) {
//flag to track whether the new item exists in the list
boolean itemExists = false;
//go through the list looking for an item with the passed name to update
for (Position existing : positions) {
if (existing.getName().equals(addition.getName())) {
existing.setQuantity(existing.getQuantity() + addition.getQuantity());
itemExists = true;
}
}
//if no matching item was found, add the new item
if (!itemExists) {
positions.add(addition);
}
}
The above should work. If you care about performance, it might be better to use a HashMap so you can look up the Position by name instead of looping through the whole list each time.
If you are interested to know other data Structure , i want suggest you HashSet , by default it will not insert duplicates for primitive objects .
In your case the only thing you need to do to your Position class , is to add
equals and hashCode methods . As getters and setters Eclipse for example will create by him self .
hashCode()
As you know this method provides the has code of an object. Basically the default implementation of hashCode() provided by Object is derived by mapping the memory address to an integer value. If look into the source of Object class , you will find the following code for the hashCode. public native int hashCode(); It indicates that hashCode is the native implementation which provides the memory address to a certain extent. However it is possible to override the hashCode method in your implementation class.
equals()
This particular method is used to make equal comparison between two objects. There are two types of comparisons in Java. One is using “= =” operator and another is “equals()”. I hope that you know the difference between this two. More specifically the “.equals()” refers to equivalence relations. So in broad sense you say that two objects are equivalent they satisfy the “equals()” condition. If you look into the source code of Object class you will find the following code for the equals() method.
Here a complete working example ( you can modify your class following this cose)
import java.util.HashSet;
public class Zhashset{
private int num;
public Zhashset(){
}
public int getNum() {
return num;
}
public void setNum(int num) {
this.num = num;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + num;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Zhashset other = (Zhashset) obj;
if (num != other.num)
return false;
return true;
}
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
HashSet<Zhashset> hs = new HashSet<Zhashset>();
hs.add(new Zhashset());
hs.add(new Zhashset());
for(Zhashset item : hs)
System.out.println(item.getNum());
}
}
Output will be : 0 written only once.

How to make an addAll() or addRange() method from scratch in java?

I'm trying to do a linkedlist for an assigment i have, this ask explicitly to create, from scratch a linkedlist and some derivated types like a queue and a stack, this is just some college homework, and i realize how to make a node class and a linkedlist class, but i'm struggling to create the addAll() method in this linkedlist class, this is what i have.
if i must bet, i say is the Collection c one, but then, i'm trying to add list of stuff there, in order to pass him's content to the new list, obiusly is not ready and obiusly doesn't work.
Can you tell me how i can pass some kind of "proto-list" in order to pass them data inside the new list?
(I know i must use somekind of for(objects) but i'm failing to pass some data through the parameter, which will be the right parameter to put there?)
public boolean addAll(Collection c) {
for (int i = 0; i < (this.listaNodos.size()); i++) {
//for (T someT : c){
// Node newNodo = new Node(someT);
//}
//i know the one down there is not gonna do anything, because
//i'm not accesing the data, but one problem at a time would ya ;)
Node newNodo = new Node(someT);
Node actualNodo = this;
boolean processFinished = false;
try{
if(index >= this.listaNodos.size() || index < 0){
throw new IndexOutOfBoundsException();
}
do{
if(index == actualNodo.getIndex())
{
actualNodo.setData(someT);
processFinished = true;
return true;
}
else
{
actualNodo = actualNodo.nextNode;
}
}while(!processFinished);
return false;
}catch(IndexOutOfBoundsException ex)
{
throw ex;
}
}
return false;
}
Can you tell me how to fix it to make it work?
Any request for clarification, constructive comment, or question would be greatly apreciated too.
Thanks in advance
I assume you already have an add() method of some sort right? If so, you can go over each element in c and add it using the add method:
public boolean addAll(Collection<T> c) {
boolean changed = false;
for (T t:c) {
changed |= this.add(t);
}
return changed;
}
I'm assuming the returned boolean means whether this list has changed, this is how it is defined in the Collection contract: https://docs.oracle.com/javase/7/docs/api/java/util/Collection.html#addAll(java.util.Collection).
You were also missing a generic type for your add method, so I added one. I assume your class definition looks somthing like this?
public class MyLinkedList<T>

How to check all members of an array

I am writing a text-based survival simulator that uses an array of Entitys. The Entity class contains data about each entity, such as energy, hydration, and morale. I'm starting to wrap up the project but I have a problem. In order to write a checkStatus() method, I need to have an if statement that checks for Entity[].isAlive on all entities, even if I don't know how long the array is. In short, how can I use an if statement to check for the value of all members of an array? I know I will probably have to use a for loop to iteratively check the members, with the array.getLength. So far I can only check variables in single classes. I have seen similar questions but they don't quite get what I'm looking for.
P.S. I'm using basic Java, with no frameworks or libraries.
Pseudo-code that demonstrates what I'm looking for
if Entity[ALL-MEMBERS].isAlive {
gameOver = true;
}
Java 6, 7, and 8:
public boolean areAllAlive(Entity[] entities) {
if(entities == null || entities.length == 0) {
return false; //?
}
for(Entity e : entities) {
if(!e.isAlive()) {
return false;
}
}
return true;
}
Java 8, using streams/functions:
public boolean areAllAlive(Entity[] entities) {
if(entities == null || entities.length == 0) {
return false; //?
}
return Arrays.stream(entities).allMatch(e -> e.isAlive());
}
First, since you probably don't know the number of Entities you are going to use before hand an ArrayList is probably a better choice. Then yes, you should use an enhanced for loop:
List<Entity> list = new ArrayList<>();
public void addEntities(){
//add Entities here
}
public boolean ifAlive(){
for (Entity e: list){
if (!e.isAlive()){
return false;
}
}
return true;
}
or something like that.
Assuming array is your entity's array, try this.:
for (int i = 0; i < array.length; i++) {
Entity entity = array[i];
if (entity.isAlive) {
gameOver = true;
//your code here
}
}

Homemade Stack Equals method

For my data structures class, we have to create our own Stack data type and the implementation for it as a project. The problem I'm running into is when the professor asked us to implement an equals(Object object) method. Heres what I have so far...
package stack;
import list.*;
public class Stack <E>
implements StackADT<E>//the interface
{
List <E> values;
public Stack()
{
values = new ArrayList<E>();
}
public E push(E value)
{
values.add(value);
return value;
}
public E pop()
{
return values.remove(values.size()-1);
}
public E peek()
{
return values.get(values.size()-1);
}
/** #return true only if this Stack is empty */
public boolean isEmpty()
{
return (values.size()==0);
}
/** Clear this stack, to make it an empty stack */
public void clear()
{
for (int i = 0; i < values.size()-1; i++)
{
pop();
}
}
public String toString()
{
String result = "[";
for (int i = 0; i<values.size(); i++)
{
if (i == values.size()-1)
{
result = result + values.get(i);
}
else
{
result = result + values.get(i) +",";
}
}
result = result + "]";
return result;
}
public boolean equals (Object object)
{
if (!(object instanceof StackADT))
{
return false;
}
StackADT <E> otherStack = new Stack<E>();
for(Object o: object)//heres where i run into trouble
{
otherStack.push(o);
}
for (int i=0;i<values.size()-1;i++)
{
if (!(values.get(i).equals(otherStack.pop())))
{
return false;
}
}
return true;
}
}
Our Stack is pretty much an ArrayList which we also built in our class. the problem is, I cant add the Object object into a stack because its not something thats iteratable(?able to be iterated over). Is there a better way to do this? I would think a get() would work, since the Stack I create is an ArrayList, but whenever I use get() on otherStack, it can't find the method. I had a temporary solution when I tried casting object as a stack(I hope im using the right terminology). It looked something like this
Stack otherStack = (Stack) object;
for (int i=0;i<values.size()-1;i++)
{
if (!(values.get(i).equals(otherStack.pop())))
{
return false;
}
}
return true;
}
this seemed to work, but when pop() was called on otherStack, the values in the original list(the one that becomes otherStack) that was passed into the equals() method we're also popped from the original list, leading to an incorrect result. Is there a better way to do this without adding in any other methods? I'm trying to stick as close to the formula set up by my professor as possible, so I dont want to add any extra fields or methods.
any and all help is appreciated
An equals method is not supposed to create anything, not even a temporary object. Rather than creating a new otherStack, cast the object that you have checked to be StackADT, like this:
// This should be the first line of any equals() implementation:
if (object == this) {
return true;
}
// You've got this part right: you need to check the other object's type
if (!(object instanceof StackADT)) {
return false;
}
// Now that you know the type, cast the other object to StackADT<E>
StackADT<E> otherStack = (StackADT<E>)object;
// The next step is to check the sizes:
if (values.size() != otherStack.values.size()) {
return false;
}
// Finally, go through the individual elements in a loop
In the loop that follows, do not pop the other stack. Do not do anything that can modify it. Simply go through the underlying storage (i.e. values), and check elements one by one.
Don't forget to override hashCode as well: you need to do it every time when you override equals for the object to fulfill the contract specified by java.lang.Object.

How to change one Boolean based on values found in ArrayList?

I am trying to make a deductive Algorithm for solving a Sudoku puzzle. My Board is made up of 81 Nodes in an ArrayList.
- Each Node has a boolean Value
I want my algorithm (called CRME) to be continue to try and solve the puzzle if it finds that at least one of the nodes has it's boolean value (hasChanged) equal to true but I am unsure how to do this. canChange is also a global variable in the class this method is contained in.
public void CRME() {
canChange = true;
while (canChange == true) {
for (Node node : cells) {
scanColumn(node);
scanRow(node);
scanMiniGrid(node);
}
}
}
public void scanRow(Node n){
for(Node node : cells){
int arraySize = node.posVals.size();
ArrayList<Integer> toRemove = new ArrayList<Integer>();
if(node.get_ROW_ID() == n.get_ROW_ID()){
toRemove.add(node.getValue());
}
n.posVals.removeAll(toRemove);
if(arraySize < node.posVals.size()){
node.hasChanged = true;
}
}
}
This is the scanRow method, the two other similarly named methods are the same but with the obvious syntax changed, such as node.get_ROW_ID(); would be node.get_COL_ID();.
I assume you have a static variable
static boolean hasChanged; // in the Node class
so you can use:
node.hasChanged = true;
or you can create hasChange method to set the variable like so
boolean hasChanged;
public void hasChanged(boolean val){
this.hasChanged = val;
}
and use in the loop, like so:
hasChanged(true); or hasChanged(false);
Not saying your approach is best, but if you are trying to simply continue while one of hasChanged is true for any of your nodes, the following will suffice:
public void CRME()
{
goOn = false;
for (Node node : yourArrayListOfNodes)
{
if (node.hasChanged)
{
goOn = true;
break;
}
}
if (goOn)
{
//Insert Whatever code you want to run after the check
//.........................................
//Use recursion to repeat process
//Note recursive call will only take place if goOn is true
CRME()
}
}
This seems like what you want to do, just note that if your logic is incorrect, you can get a StackOverflowError, since you would keep making recursive calls.

Categories