After developing in PHP for a long time I have decided to step into Java. Comfortable in OOP methodology and all that, I'm trying to start off at that point within java, but I'm getting hung up on passing out my arraylist object into a for statement to be printed back out using the Item class methods.
HelloInvetory.java
package helloInventory;
import java.util.Arrays;
public class HelloInventory {
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Object InvetoryItems;
Inventory inv = new Inventory();
inv.createItemObj(101, "camera", "Used camera that I bought off of a homeless guy.", 500);
InvetoryItems = inv.getAllInventoryItems();
for(Object item : InvetoryItems){
System.out.println(item.getItemName());
}
System.out.println("Done");
}
}
Inventory.java
package helloInventory;
import java.util.*;
/**
* Tracks and maintains all items within the inventory
* #author levi
*
*/
public class Inventory {
List<Object> InventoryItems = new ArrayList<Object>();
/*
* create object from Items class
* and insert into Object[] array.
*/
public void createItemObj(int sku, String name, String descriptor, float price) {
Items item = new Items();
item.setSku(sku);
item.setItemName(name);
item.setItemDescription(descriptor);
item.setItemPrice(price);
this.setInventoryItems(item);
}
public Object getAllInventoryItems() {
//return InventoryItems;
return this.InventoryItems.toArray();
}
public void setInventoryItems(Object inventoryItems) {
//InventoryItems.add(inventoryItems);
this.InventoryItems.add(inventoryItems);
}
}
Items.java
package helloInventory;
/**
* Class object to hold each item details
* #author levi
*
*/
public class Items {
int sku;
String itemName;
String itemDescription;
float itemPrice;
public int getSku() {
return sku;
}
public void setSku(int sku) {
this.sku = sku;
}
public String getItemName() {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public String getItemDescription() {
return itemDescription;
}
public void setItemDescription(String itemDescription) {
this.itemDescription = itemDescription;
}
public float getItemPrice() {
return itemPrice;
}
public void setItemPrice(float itemPrice) {
this.itemPrice = itemPrice;
}
}
Where I am stuck is within the HelloInventory.java
for(Object item : InvetoryItems){
System.out.println(item.getItemName());
}
IDE (Eclipse) gives me the error "Can only iterate over an array or an instance of java.lang.Iterable". Is there something extra I need, or I'm I going around this totally the wrong way in Java? Correct example would be helpful.
Best,
Levi
You have a very strange architecture here my friend. You shouldn't be using generic Objects everywhere, but the actual types. First thing:
public Object getAllInventoryItems() {
//return InventoryItems;
return this.InventoryItems.toArray();
}
Why not just return the List itself?
public List<Item> getAllInventoryItems() {
return this.InventoryItems;
}
Also change this:
List<Item> InventoryItems = new ArrayList<Item>();
and this:
public void setInventoryItems(Item inventoryItems) {
this.InventoryItems.add(inventoryItems);
}
Now iterating the List is smooth sailing:
public static void main(String[] args) {
// TODO Auto-generated method stub
List<Item> InvetoryItems;
Inventory inv = new Inventory();
inv.createItemObj(101, "camera", "Used camera that I bought off of a homeless guy.", 500);
InvetoryItems = inv.getAllInventoryItems();
for(Item item : InvetoryItems){
System.out.println(item.getItemName());
}
System.out.println("Done");
}
Btw, I changed Items to Item out of habit. A class name should indicate a single entity so by convention it's singular.
Now don't take this the wrong way, but you may have got off on the wrong foot with Java, so I highly recommend this reading: http://www.mindview.net/Books/TIJ/ This worked for me when I was starting with Java, maybe others can suggest some good sources as well.
Ok, two things. One is that Tudor is absolutely right, it's best to use the classes you're expecting directly, not Objects, and stylistically his points are accurate too.
Two is that if you really have to use a list of object, you'll need to cast back from object to whatever type it is that you're expecting to receive.
List<Object> list = inv.getAllInventoryItems();
for (Object item : list){
System.out.println((Items) item).getItemName();
}
However, I wouldn't recommend doing this as it effectively takes what should be a compile-time error and makes it a RunTime error (if the class cannot be cast).
Related
Hi i have this class Item
public class Item implements Cloneable {
private String name;
private int reorderAmount;
public Item(String name, int reorderAmount) {
this.name = name;
this.reorderAmount = reorderAmount;
}
/**
* #return The Amount of a reorder.
*/
public int getReorderAmount() {
return reorderAmount;
}
}
My other class is Stock
public class Stock extends HashMap {
private HashMap<String, Item> stock;
/**
* Constructor. Creates a stock.
*/
public Stock() {
stock = new HashMap<>();
}
/**
* Calculates the total Quantity of Items for the next Order.
* #return Number of total reorder quantity.
*/
public int getTotalReorderAmount() {
int reorderQuantity = 0;
for (Item item : (Collection<Item>) this.values()) {
reorderQuantity += item.getReorderAmount();
}
return reorderQuantity;
}
}
I'm having trouble running my JUnit test as my understanding on how one class effects another is lacking.
public class StockTests {
Stock stock;
Item item;
// Clear the item and stock object before every test
#Before
public void setUp() {
String name = "bread";
Integer reorderAmount = 100;
item = new Item(name, reorderAmount);
stock = null;
}
/*
* Test 1: Test the total number of items needed.
*/
#Test
public void testReorderAmount() {
stock = new Stock();
assertEquals(100, stock.getTotalReorderAmount());
}
}
What I have currently done is created an Item 'bread' inside the #before of my Junit testing class with 100 as the reorder amount. I am testing to see if my method getTotalReorderAmount inside my Stock Class is returning 100 however my JUnit results tell me it is returning 0. This is where i believe that i am creating the Item incorrectly within the JUnit Class.
You create an item, but never add it to the Stock.
A simplistic implementation:
public class Stock {
....
public void add(Item item) {
stock.put(item.getName(), item);
}
}
Your test could be:
/*
* Test 1: Test the total number of items needed.
*/
#Test
public void testReorderAmount() {
Stock stock = new Stock();
stock.add(new Item("bread", 100));
assertEquals(100, stock.getTotalReorderAmount());
}
No need to use setUp in this case.
By the way, the most basic testcase (which is advisable to start with) is the empty stock:
#Test
public void emptyStock() {
Stock stock = new Stock();
assertEquals(0, stock.getTotalReorderAmount());
}
In your testReorderAmount method, you have to set item you created.
Firstly modify your Stock class to have a method which adds item in private HashMap<String, Item> stock.
i.e. you class Stock could look like:
public class Stock {
.............
private HashMap<String, Item> stock;
public void addItemToStock(String itemName, Item item){
stock.put(itemName, item);
}
/**
* Constructor. Creates a stock.
*/
public Stock() {
stock = new HashMap<>();
}
.........
}
Secondly, set the item inside the stock map in your junit test.
Your test method will look like :
/*
* Test 1: Test the total number of items needed.
*/
#Test
public void testReorderAmount() {
stock = new Stock();
stock.addItem("bread", this.item);
assertEquals(100, stock.getTotalReorderAmount());
}
I am trying to retrieve certain values from multiple objects under the same class. I have used a for each loop to iterate through each object, and would like to create an aggregated total, representing the rating and the cost of the item from the objects.
The For Each loop in my parent class:
for (Song songObj : Song.returnSongs()) {
totalSongCost += Double.parseDouble(songObj.getPrice());
totalSongRating += Integer.parseInt(songObj.getRating());
}
The Child class ArrayList meant to store objects:
private int rating;
private String title;
private double price;
private boolean favorite;
private static int counter = 0;
private static ArrayList songArray = new ArrayList();
/**
* Constructor for objects of class Song
*/
public Song()
{
// initialise instance variables
rating = 0;
title = "";
price = 0.0;
counter++;
songArray.add(this);
}
public static ArrayList returnSongs() {
return songArray;
}
When I compile the code I get an error message saying that an object cannot be converted to song. Is there a way to fix this, or an easier way to accomplish the same task?
If you've ever read the docs, you will know that ArrayList is actually a generic class. That means you can give ArrayList a type.
The type of stuff that an array list can store depends on what type you gave it. But if you don't give it any type, it stores Objects! Here,
for (Song songObj : Song.returnSongs()) {
you want to get Song objects from an array list of Object objects, which makes no sense to the compiler. As a result, the error appears.
The solution to this problem is of course, give the array list a type so that it knows what type it should store.
Change this
private static ArrayList songArray = new ArrayList();
to this:
private static ArrayList<Song> songArray = new ArrayList<>();
and change this:
public static ArrayList returnSongs() {
to this:
public static ArrayList<Song> returnSongs() {
ArrayList is a generic class. This means you can specify what class type it is meant to work with. if you change this:
private static ArrayList songArray = new ArrayList();
to this:
private static ArrayList<Song> songArray = new ArrayList<Song>();
Then the ArrayList class will understand that you're working with instances of Song.
Edit: as Jim Garrison pointed out, your returnSongs() method should also be changed to specify the class type in the same way.
public static ArrayList<Song> returnSongs() { ...
It's a little unusual to have the Song class be responsible for keeping track of all of the songs within the application. That seems outside of the responsibility of that class, and perhaps better suited to be handled within a different class, either within your parent class or a new type specially defined.
Additionally, be careful when using types like List and ArrayList. As your compiler will warn you, these require type parameters in angle brackets (i.e. List<Type>). You should make it a habit of addressing all compiler warnings, and of always specifying type parameters for generic types like List. In cases where you don't define your types correctly, things start to default to Object, which leads to the issue you faced here.
Below is an example of what this could look like, restructured to keep the Song class solely for attributes of the song itself:
import java.util.ArrayList;
import java.util.List;
public class Parent {
private static List<Song> songs = new ArrayList<Song>();
private static double totalSongCost = 0.0;
private static int totalSongRating = 0;
public static void main(String[] args) {
populateSongs();
for (Song song : songs) {
totalSongCost += songObj.getPrice();
totalSongRating += songObj.getRating();
}
}
private void populateSongs() {
songs.add(new Song(5, "Hey Jude", 12.5));
songs.add(new Song(4, "Angie", 11.5));
songs.add(new Song(0, "Other", 10.5));
}
}
Your song class would simply be this:
public class Song {
private int rating = 0;
private String title = "";
private double price = 0.0;
public Song(int rating, String title, double price) {
this.rating = rating;
this.title = title;
this.price = price;
}
// Compressed for brevity
public int getRating() { return rating; }
public String getTitle() { return title; }
public double getPrice() { return price; }
}
i have the following problem: I read out database items in an observable list. Now I want to display some items from the selected line in a few textfields on the right side of my tableview.
I got the observable-line-index with the following code, but I want to select an other column of the line.
AnalysemethodenTable.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Object>() {
public void changed(ObservableValue<?> observable, Object oldvalue, Object newValue) {
index.set(analysemethodendata.indexOf(newValue));
databaseIndex = (analysemethodendata.indexOf(newValue) + 1);
System.out.println("Index:\t" + databaseIndex);
}
});
I found the following code: Click
But i don't understand this. It's something like to write a new list and place a copy of the items of the observable list in this new list.
I think, if I have the index of the line with my code, I can select the other items in the line of the observable list, too (I thought like "x,y" like an array)
If i cast it to String, the output is only machine code.
Hope I can understand the solution with your help!
EDIT: I inserted the following code:
System.out.println(analysemethodendata.get(databaseIndex).toString());
But I only get machine code in my Output:
table.analysemethoden_table#63c0d5b7
EDIT 2:
Table-Controller-Code:
package table;
import javafx.beans.property.SimpleFloatProperty;
import javafx.beans.property.SimpleStringProperty;
public class analysemethoden_table {
private final SimpleStringProperty rAmnorm;
private final SimpleStringProperty rMethverantw;
private final SimpleFloatProperty rBestimmungsgrenze;
private final SimpleFloatProperty rNachweisgrenze;
public analysemethoden_table (String sAmnorm, String sMethoverantw, Float sBestimmungsgrenze, Float sNachweisgrenze) {
this.rAmnorm = new SimpleStringProperty(sAmnorm);
this.rMethverantw = new SimpleStringProperty(sMethoverantw);
this.rBestimmungsgrenze = new SimpleFloatProperty(sBestimmungsgrenze);
this.rNachweisgrenze = new SimpleFloatProperty(sNachweisgrenze);
}
// Getter- und Setter-Methoden
/** rAmnorm **/
public String getRAmnorm() {
return rAmnorm.get();
}
public void setRAmnorm(String set) {
rAmnorm.set(set);
}
/** rMethverantw **/
public String getRMethverantw() {
return rMethverantw.get();
}
public void setRMethverantw(String set) {
rMethverantw.set(set);
}
/** rBestimmungsgrenze **/
public Float getRBestimmungsgrenze() {
return rBestimmungsgrenze.get();
}
public void setRBestimmungsgrenze(Float set) {
rBestimmungsgrenze.set(set);
}
/** rNachweisgrenze **/
public Float getRNachweisgrenze() {
return rNachweisgrenze.get();
}
public void setRNachweisgrenze(Float set) {
rNachweisgrenze.set(set);
}
}
You need to use
analysemethodendata.get(databaseIndex).getRAmnorm();
or any other getter method in place of getRAmnorm() to get the required output.
databaseIndex -> row number
I have a four classes Book Disk Paper Magazine all of them derive from another class Items and all of them have a String barcode field.
In another class foo I have ArrayList<Book> books; ArrayList<Disk> disks; ArrayList<Paper> papers; ArrayList<Magazine> magazines;, and I want to implement for each one of these a getByBarcode(String barcode) method, that would look in the arraylist for the item with that barcode. If it's a book it has to look in the books list etc.
Can I avoid having to do four different ones? What I mean is avoiding having to do a getBookByBarcode(String barcode) that would have to look in the books list, getDiskByBarcode(String barcode) that would have to look in the disks list etc..
And have a generic one like public Object getByBarcode(String barcode,type). How do I do this nicely in an OOP way?
Essentially every Book, Magazine, Disk & Paper is an Item. Hence you should have a parent class named Item and not its plural form. Every Base Class should classify as a singular entity.
You should then create objects of Book, Magazine, Disk & Paper. Since all of these classify as an Item, create an array list of type Item and add these objects to the same.
This way you have a item list which has books, magazines, disks & papers. You can then look into this list for an item with barcode and get the type of item.
Source Code:
Item.java
package myLibrary;
public class Item {
protected String barcode;
public String getBarcode() {
return barcode;
}
public void setBarcode(String barcode) {
this.barcode = barcode;
}
public Item(String barcode) {
this.barcode = barcode;
}
}
Book.java / Disk.java / Magazine.java / Paper.java
package myLibrary;
public class Book extends Item {
public Book(String barcode) {
super(barcode);
}
public String getBarcode() {
return barcode;
}
}
Lecturer.java (Class containing main function)
package myCollege;
import java.util.ArrayList;
import myLibrary.Book;
import myLibrary.Disk;
import myLibrary.Item;
import myLibrary.Magazine;
import myLibrary.Paper;
public class Lecturer {
public static void main(String[] args) {
// Declare items
Book x1 = new Book("Item101");
Book x2 = new Book("Item102");
Disk x3 = new Disk("Item201");
Disk x4 = new Disk("Item202");
Magazine x5 = new Magazine("Item301");
Paper x6 = new Paper("Item401");
Paper x7 = new Paper("Item402");
ArrayList<Item> items = new ArrayList<>();
items.add(x1);
items.add(x2);
items.add(x3);
items.add(x4);
items.add(x5);
items.add(x6);
items.add(x7);
String itemType = getItemByBarcode("Item202", items);
System.out.println(itemType);
}
private static String getItemByBarcode(String barcode, ArrayList<Item> items) {
String itemType = "";
for(Item i : items) {
if(i.getBarcode().equalsIgnoreCase(barcode)) {
itemType = i.getClass().getSimpleName();
}
}
return itemType;
}
}
Output:
Disk
I hope this helps in better understanding of the concept/issue.
may sound hackish but you can do like some other users suggested and call
public Object getByBarcode(String barcode, Class<T> classy)
{
ArrayList<Items> items = null;
if(classy.class.getSimpleName().equals(Book.class.getSimpleName()))
items = bookArray;
else if(classy.class.getSimpleName().equals(Magazine.class.getSimpleName()))
items = magazineArray;
else
... cnt'd
for(Item i : items)
if( i.getBarCode().equals(barcode) return i;
}
Then to call this beastly mess you could do something like . . .
Item i = getByBarCode("0932A3", Book.class);
I am trying to write an if condition to check a value exists in a list containing many objects,
Here is my code:
List<TeacherInfo> teacherInfo=ServiceManager.getHelperService(TeacherManagementHelper.class, request, response).getTeacherInfoId();
if(teacherInfo.contains(inputParam))
{
out2.println("<font color=red>");
out2.println("Id Not Available");
out2.println("</font>");
}
else
{
out2.println("<font color=green>");
out2.println("Id Available");
out2.println("</font>");
}
after executing 1st sentence getTeacherInfoId() method successfully returns a list of objects, in those objects I want to check any object has a value same as inputParam. Is my above code right ? if wrong please help me .
contains(Object o) is internally based on equals between objects of your list and your input, as stated by the doc.
Since you said that inputParam is an integer, then the current state of your code can't work because you compare an integer to TeacherInfo objects, so they won't ever be equal. I believe you want to compare inputParam to one particular field of TeacherInfo objects.
If you're using Java 8, you can use the stream API instead of contains():
List<TeacherInfo> teacherInfo=ServiceManager.getHelperService(TeacherManagementHelper.class, request, response).getTeacherInfoId();
if (teacherInfo.stream().anyMatch(ti -> ti.getId() == inputParam)) {
// contains the id
} else {
// does not contain the id
}
For previous java versions, an alternative to contains() would be to iterate over your list and compare manually your integer to the TeacherInfo's field:
private static boolean containsTeacherId(List<TeacherInfo> teacherInfos, int id) {
for (TeacherInfo ti : teacherInfos) {
if (ti.getId() == inputParam) { // I used getId(), replace that by the accessor you actually need
return true;
}
}
return false;
}
Then:
List<TeacherInfo> teacherInfo=ServiceManager.getHelperService(TeacherManagementHelper.class, request, response).getTeacherInfoId();
if (containsTeacherId(teacherInfo, inputParam)) {
// contains the id
} else {
// does not contain the id
}
Note: If you don't need other information than the ID itself, I'd rather suggest to return the list of IDs from a method called getTeacherIds(), especially if this information comes from a DB.
No it won't work at all. you should iterate the 'teacherInfo' list and you need to override the compare()and hashvalue() of object class.
You would need to iterate over the list teacherInfo and compare each element of that list with inputParam.
Below is a small demo code that might help you.
I have created a testerInfo analogous to your teacherInfo and param analogous to your inputParam.
I hope it helps.
Tester.java
/**
*
*/
package com.demo;
/**
* #author Parul
*
*/
public class Tester {
private int id;
private String name;
/**
* #return the id
*/
public int getId() {
return id;
}
/**
* #param id the id to set
*/
public void setId(int id) {
this.id = id;
}
/**
* #return the name
*/
public String getName() {
return name;
}
/**
* #param name the name to set
*/
public void setName(String name) {
this.name = name;
}
public Tester(int id, String name) {
this.id = id;
this.name = name;
}
public Tester() {
}
}
Demo.java
/**
*
*/
package com.demo;
import java.util.ArrayList;
import java.util.List;
/**
* #author Parul
*
*/
public class Demo {
public static void main(String [] args){
List<Tester> testerInfo=new ArrayList<Tester>();
testerInfo.add(new Tester(1,"Java"));
testerInfo.add(new Tester(2,"C++"));
testerInfo.add(new Tester(3,"Python"));
testerInfo.add(new Tester(4,"C"));
Tester tester=null;
int param=2;
for(int i=0;i<testerInfo.size();i++){
tester=testerInfo.get(i);
if(tester.getId()==param){
System.out.println("param found: "+tester.getName());
break;
}
}
}
}
OUTPUT
param found: C++