I have these class on my package:
1. Class Goods with attributes (name, price, id) //Goods id is unique, but the name can be the same
2. Class Storage with attributes (Goods gArray[3])
3. Class Store with attributes (name, ArrayList<Storage>) //Store name is unique
4. Class StoreSystem with attributes (ArrayList<Store>)
I want to insert Goods into Storage which belong to certain Store. I already succeed in inserting the Store to ArrayList, but haven't found the way to insert the Goods.
Here's the code for adding the store:
public String addStore(String storeName) {
String output = "";
if(storeCheck(storeName)) { //storeCheck used to check whether the store name exist/not.
output = "store already exist!";
}
else {
Store s1 = new Store();
Storage st1 = new Storage();
s1.setStoreName(storeName);
s1.setStorageList(null);
st1.setGArray(null);
listOfStore.add(s1);
listOfStorage.add(st1);
output = "Store added";
}
return output;
}
You could create a method in the Storage class that:
either takes an index of the array and Goods as arguments and places the Goods in the array at that index (if you're interested in full control of where everything goes)
or just Goods as argument and decides where to put them internally (if you do not care which index in the array the goods go to)
Does that make sense?
I believe is just this, using list as intermediate:
public void addGoods(Goods g) {
List<Goods> storageList = Arrays.asList(this.getGoods());
storageList.add(g);
this.setGoods(storageList.toArray());
}
get and set as usual, and you will need to control the size.
Make a POJO called Storage with the field Goods gArray[3]. Then have a method to add Storage in Store class (it should be as simple as using storeArrayList.add(new Storage()); and pass 3 parameters of type Goods to it). And there you go. You have a Storage and Goods in Storage.
Now properly looking up for a particular Storage in a Store without assigning an index to a particular Storage will be a bit of a bother. Ideally, every Storage object should have an id field.
The code will look something like:
The Store add method:
<return-type> addToStore(Goods[] goods) {
storageArray.add(new Storage(goods));
}
And then the Storage class will look something like:
class Storage {
private final Goods gArray[3];
public Storage(final Goods gArray) {
this.gArray = gArray;
}
// getters
}
Related
I have a class for creating basic grocery store items (class storeItems). I want to allow the user to make their own grocery store item by creating a new class object based on parameters that I receive from the user; i.e: "What is the name?" "What is the price?" "How much in stock?" etc. I also do not want to define the number of objects that can be created, so that it can be expanded as needed by the user.
Everything is properly structured, other than the object variable names themselves.
How would I go about creating these objects? Most of my Googling has suggested to use maps, but I can't for the life of me figure out how I would structure this.
This is essentially what I am trying to do:
public static Map<String,storeItems> storeItemMapper = new HashMap<String,storeItems>();
public static void itemBuilder(String mapObjName, String itemName, double price, int initialQuantity) {
storeItems object[i] = new storeItems(itemName, price, initialQuantity);
storeItemMapper.put(mapObjName, object[i]);
}
You are wrongly indexing the variable declaration:
storeItems object[i] = new storeItems(itemName, price, initialQuantity);
Try:
storeItems object = new storeItems(itemName, price, initialQuantity);
Without the index [i]. And as I said in the commentary, you should to use the CamelCase standard to name classes:
StoreItems object = new StoreItems(itemName, price, initialQuantity);
I am trying to replace element in collection with new modified version. Below is short code that aims to demonstrate what I'd like to achieve.
The whole idea is that I have one object that consists of collections of other objects. At some point in time I am expecting that this objects in collections (in my example phones) might require some modifications and I'd like to modify the code in one place only.
I know that in order to update the object's attributes I can use setters while iterating through the collection as demonstrated below. But maybe there is better, more general way to achieve that.
public class Customer {
private int id;
private Collection<Phone> phoneCollection;
public Customer() {
phoneCollection = new ArrayList<>();
}
//getters and setters
}
and Phone class
public class Phone {
private int id;
private String number;
private String name;
//getters and setters
}
and
public static void main(String[] args) {
Customer c = new Customer();
c.addPhone(new Phone(1, "12345", "aaa"));
c.addPhone(new Phone(2, "34567", "bbb"));
System.out.println(c);
Phone p = new Phone(2, "9999999", "new name");
Collection<Phone> col = c.getPhoneCollection();
for (Phone phone : col) {
if (phone.getId() == p.getId()) {
// This is working fine
// phone.setNumber(p.getNumber());
// phone.setName(p.getName());
// But I'd like to replace whole object if possible and this is not working, at least not that way
phone = p;
}
}
System.out.println(c);
}
}
Is this possible to achieve what I want?
I tried copy constructor idea and other methods I found searching the net but none of them was working like I would expect.
EDIT 1
After reading some comments I got an idea
I added the following method to my Phone class
public static void replace(Phone org, Phone dst){
org.setName(dst.getName());
org.setNumber(dst.getNumber());
}
and now my foreach part looks like that
for (Phone phone : col) {
if (phone.getId() == p.getId()) {
Phone.replace(phone, p);
}
}
And it does the job.
Now if I change the Phone class attributes I only need to change that method. Do you think it is OK solving the issue that way?
You should not modify the collection while you're iterating through it; that's likely to earn you a ConcurrentModificationException. You can scan the collection for the first object that matches your search criterion. Then you can exit the loop, remove the old object, and add the new one.
Collection<Phone> col = c.getPhoneCollection();
Phone original = null;
for (Phone phone : col) {
if (phone.getId() == p.getId()) {
original = phone;
break;
}
}
if (original != null) {
Phone replacement = new Phone(original);
replacement.setNumber(p.getNumber());
replacement.setName(p.getName());
col.remove(original);
col.add(replacement);
}
Alternatively, you could declare a more specific type of collection, such as a List, that would allow you to work with indexes, which would make the replacement step much more efficient.
If your phone IDs are unique to each phone, you should consider using a Map<Integer, Phone> that maps each phone ID to the corresponding phone. (Alternatively, you could use some sort of third-party sparse array structure that doesn't involve boxing each ID into an Integer.) Of course, if your IDs aren't unique, then you might want to modify the above to gather a secondary collection of all matching phones (and reconsider the logic of your existing code as well).
You can also use a Set (HashSet), this is only when you don't want to do the way Mike suggested.
Use the Phone as an item in the set. Don't forget to implement hashCode() and equals() in Phone. hashCode() should return the id, as it is supposed to be unique.
Since you are concerned about replacing the item, here's how HashSet will help you :
Create an instance of your object.
Remove the object you want to replace from the set.
Add the new object (you created in step 1) back to the set.
Both these operations 2 & 3 are guaranteed in O(1) / constant time.
You don't need to maintain a map for this problem, that's redundant.
If you want to get the object from the collection itself and then modify it, then HashMap would be better, search is guaranteed in O(1) time.
Instead of a list, use a map with the Phone's id as the key. Then your code looks like this:
public static void main(String[] args) {
Customer c = new Customer();
c.addPhone(new Phone(1, "12345", "aaa"));
c.addPhone(new Phone(2, "34567", "bbb"));
System.out.println(c);
Phone p = new Phone(2, "9999999", "new name");
Map<Integer, Phone> phoneMap = c.getPhoneMap();
phoneMap.put(p.getId(), p);
System.out.println(c);
}
If you take the object out from the collection and update its properties, it will get reflected in the same object in collection too.. Hence, you dont have to technically replace object after updating it.
As "Mike M." pointed out, you can use hashmap to retrieve the object quickly without iteration and update the object values.
If order matters to you, you can change Collection to List (Since you're always using an ArrayList anyway) and then:
int index = col.indexOf(phone);
col.remove(phone);
col.add(p, index);
I am pretty new to coding. This is my first class and it's an intro to Java. I am stuck on one part of the assignment - not sure where to go.
I have an inventory program that has a Product class and a Stock class. The stock class needs to be able to use the product object in an array in methods to 1)tell if a product is in stock w. its sku. 2) return quantity with sku 3)add or remove product from Stock.
It sounds simple enough but I'm not understanding it. I've been searching the internet and reading my book for weeks to no avail so I thought I'd give this a try.
My product class contains the usual get/set methods for qty, sku, price, name
This is my Stock class:
public class Stock
{
private static final int MAX = 100;
int currentNoOfProd = 0;
Product[] productsArray = new Product[MAX];
//I need an empty stock array constructor
/* public Stock (int[] stockArray)
{
this.productsArray = stockArray;
}*/
//method to tell if Product is in Stock with SKU
public void inStock()
{
for(int i = 0; i< MAX; i++)
{
System.out.println("testing stock inventory\n" + productsArray[i].getSKU());
if (productsArray[i].getQty() > 0)
{
System.out.println("In Stock");
}
}
}
//return the quantity of a Product given its SKU
public void qtyInStock()
{
for(int i=0; i< MAX; i++)
{
System.out.println("in qtyInStock loop\n" + productsArray[i].getSKU());
System.out.println("getting quantity qtyInStock" + productsArray[i].getQty());
}
}
//add or remove a Product from Stock
}
My stock class is just me testing ideas to try and do /something/ but at this point I'm completely lost. This may be vague but I don't know how much more specific I can get.
I am hard coding the sku, name, price, and quatity in my driver program, if that helps, when I initiate a product object.
Suggestions would be wonderful or tips, anything really to help me move along and figure this out and learn. Thanks so much.
Some pointers that hopefully guide you forward:
1. Instance variables in the Stock class
By default, you should always use the "least visible" scope, i.e. private, in your instance variables. This means that Product[] productsArray should be replaced with private Product[] productsArray. Variables in the private scope can only be accessed by the containing class, which is a good thing when the class is a part of a larger application and you are debugging things.
2. Method telling whether a product is in stock or not
Your inStock() method is currently neither using a "SKU" (Stock keeping unit) for input nor returning anything back to the caller. It would seem better to change the method signature to
public boolean inStock(String sku)
instead. The iteration over productsArray looks ok, even though you can make it even more concise using the for-each construct, which has been available from Java 5 onwards (the array knows its size after it has been created):
for (Product p : productsArray) {
// you can use p.getQty() and p.getSKU() within the loop
...
}
Please note that because your array can/will contain null elements, you should check for p != null before invoking any methods on p. Basically you just need to return true from the loop when you find a match with a positive quantity and the given "SKU". Otherwise return false at the end of the method because no matches were found.
3. Return quantity of a product
The method signature should be changed to
public int qtyInStock(String sku)
If we assume that productsArray only holds one Product for a given "SKU", then you can simply iterate over the array and return the quantity of a product if one is found.
4. Add or remove product from Stock.
You probably want to split this requirement into two different methods: one for adding and one for removing stuff from your stock. For example:
public void addProduct(Product p)
and
public void removeProduct(Product p)
These are more difficult methods to implement, because they require manipulating the underlying productsArray. Also, in a real life application, the method would possibly throw an Exception if something unexpected happens (stock out of space, product not in stock etc.).
If we assume that your MAX array size is large enough, and that you only store one Product per "SKU" in the array, then basically you need to:
When adding a product: Iterate over the array and try to find a product with a "SKU" matching the input product's "SKU". If a match is found, increment the quantity based on the quantity of the input product; else store the product in the first available slot (having productsArray[i] == null) in the array.
When removing a product: if a match is found in the array, just set it to null using productsArray[i] = null.
Note that in these array-modifying methods, it is more practical to iterate using the for loop that keeps track of the index (for (int i = 0; i < MAX; i++)), which you already used in your example code.
You should use a Collection, e. g. ArrayList<Product> instead of Product[]. Your stock would not have fixed size and you will get some useful API as for example list.add(product), list.contains(product) etc.
So i am trying to sort through a large amount of data in an CSV. file. The file includes a set amount of information for companies, but there are 1000s of companies. For example, I might need to go through 1000 companies, be able to acquire their annual earnings, current stock value, CEO, ect.. each company will have the same information provided (same number of commas but different char lengths), but as the file is a CSV. the company name and information is all separated by commas.
currently i am splitting the csv file into an array via the commas between information. But i want to be able to keep the information together with companies and be able to specify, call and, sort by the given information and company names. But because i have already separated the information via the commas its all listed out already in a listarray.
So is it possible to specify, on a mass scale, that every 15 commas (or splits in the listarray) should be joined back together?? This way each part of the listarray is a separate company. Or is there another way to separate the data so that the information doesnt get split up?
note: there is no similarities in the csv file that would allow me to split information so that it splits after each companies information.
here is a sample of what one of the csv files may look like.
"Tiffany & Co. Com",964270,"+0.81","1/14/2014",88.97,93.64,"87.795 - 88.97""Asia Pacific Fund",20700,"+0.04","1/14/2014",10.23,11.37,"10.19 - 10.23""Anadarko Petroleu",4236380,"+2.47","1/14/2014",80.99,98.47,"78.40 - 80.99""Proto Labs, Inc. ",451984,"-0.18","1/14/2014",73.83,89.97,"71.00 - 73.83""Zuoan Fashion Lim",201560,"-0.02","1/14/2014",1.79,3.62,"1.71 - 1.79"
I would agree with converting each row of CSV into Java object.
But traditional parsing mechanism is too verbose for me and I might need to handle too many conditions like comma in between quotes, new line character in a column with multiline description. So I suggest you use an existing awesome solution like supercsv.
I also have written a wrapper around it to make developer life easy.
QuickOCM will let you do this way.
Create a Company class
public class Company {
/* this specifies that
* it is a mandatory field in the csv,
* of header name "Company Name" and
* of type string.
* Header is the first line of the csv.
*/
#ImportField(mandatory = true, name = "Company Name", type = "String")
public String name;
#ImportField(mandatory = true, name = "Name of the CEO", type = "String")
public String ceoName;
}
You need public getter-setter or public fields, anything works
Create csv parser, a handler to handle each row, probably add to a list to sort, and then call parse
final List<Company> companies = new ArrayList<Company>();
csvParser.process(inputStream, Company.class, new RecordHandler<Company>() {
#Override
public void execute(Company imported, int rowNumber, Map supplementaryInfo) {
companies.add(imported);
}
});
Now you can sort the list with by using a sorted list implementation or use a comparator for the same.
For detailed info, you can look into QuickOCM page.
public class Read{
String original = "";
String company = "";
String otherValue = "";
public Read(String read){
//here Split the original string into the values
}
//public void getters and setters
}
Then make an array of Read Objects and sort them as you want
One idea would be to parse the CSV into objects and then sort those objects. The object would "know" how many fields it was made up of in the CSV and how to parse each field. Using the StringTokenizer to parse and a TreeMap to sort would look something like:
...
BufferedReader reader = new BufferedReader(new FileReader("somedata.csv"));
TreeMap<String, MyObject> map = new TreeMap<>();
String line = reader.readLine();
StringTokenizer tokens = new StringTokenizer(line,",");
while(tokens.hasMoreTokens()) {
MyObject obj = new MyObject(tokens);
//add the objects to the sorted map, where field1 is what we sort on
map.put(obj.field1, obj);
}
...
}
static class MyObject {
//would need the same number of fields as you want to group
String field1;
String field2;
//... so with 2 fields, input is field1,field2,field1,field2,...
MyObject (StringTokenizer input) {
this.field1 = input.nextToken();
this.field2 = input.nextToken();
}
}
I've implemented in-app-billing v3 and I'd like a way to keep some sort of table which contains 3 columns
(String) Name of product, (String) sku, (boolean) true/false
What is the best way to do this? The best way would (in my opinion) allow me to keep a static easily readable list of values where the first two were strings, the third a boolean. At the start all the values for the boolean column were false, but as I query purchases I am able to easily reset the value.
Just to add,
I'm against SQLite databases for the reason that they're just too easy to hack. I'd rather create it in code and thus I'm debating between an ArrayList within an arraylist or matrices or something like the following:
private static class CatalogEntry {
public String sku;
public String name;
public CatalogEntry(String sku, String name) {
this.sku = sku;
this.name = name;
}
}
private static final CatalogEntry[] CATALOG = new CatalogEntry[] {
new CatalogEntry("android.test.purchased", "Item1"),
new CatalogEntry("android.test.canceled", "Item2"),
new CatalogEntry("android.test.refunded", "Item3"),
new CatalogEntry("android.test.item_unavailable", "Item4")
};
Is there a way to reset values in the CATALOG array if I add a third column, otherwise I'm considering using both that and standard arraylists.
Use sqlite with FOUR columns:
sku
name
purchaseDate (or null if not purchased)
md5Hash
When a purchase is made, you just concatenate the sku, name, purchaseDate, device-id, and a PSK, make an md5Hash and store it along with the other data in the row. When you check the contents of the table, you compare the md5 stored against the data, and you can verify whether the purchase was valid, or the table has been tampered with. You can even let the user back up the purchase table to sdcard (or use Android backup).