This subclass should be able to let the user choose a specific employee ID, type it into the command line and choose to either add it to the array list, delete it from the array list or simply request to see more information about the specific employee ID. I've tried so many things with no luck at all.
package WorkIDServerStorage;
public class EmployeeList{
private Employee[] theEmployee;
private int arrayEmployee;
public EmployeeList(){
theEmployee = new Employee[100];
arrayEmployee = 0;
}
public EmployeeList(int arraySize){
theEmployee = new Employee[arraySize];
arrayEmployee = 0;
}
public void setTheEmployee(Employee[] inputTheEmployee){
theEmployee = inputTheEmployee;
}
public void setArrayEmployee(int inputArrayEmployee){
arrayEmployee = inputArrayEmployee;
}
public Employee[] getTheEmployee(){
return theEmployee;
}
public int getArrayEmployee(){
return arrayEmployee;
}
public Employee addEmployeeID(Employee employeeAdd){
return theEmployee[arrayEmployee++] = employeeAdd;
}
public Employee deleteEmployeeID(int employeeDelete){
//Delete an employee record with a
//specified record number from the array
}
public Employee readEmployeeInfo(int employeeRead){
//Read the employee data for a specified record number
//From the array and display this data to the screen
}
#Override
public String toString(){
StringBuilder sb = new StringBuilder();
for(int x = 0; x < arrayEmployee; x++){
sb.append(theEmployee[x].toString()).append("\n");
}return sb.toString();
}
}
Arrays are fixed length data structures. They are much like a multi-storied building. You can't take a floor out from the middle of the building and expect it to stand.
ArrayList (as others have pointed out), are dynamic structures, much like a train. You can take out compartments as you wish, you can reconfigure it.
I would in fact recommend NOT using a List at all, but a Map that maps an ID to an employee record. Let us say you have the following employees in a list -
Alice
Bob
John
Ruth
If you delete "Bob" the ID's for John and Ruth are going to change. Not a good practice. If you use a Map instead, everyone can keep their assigned ID's and you just add to the map by incrementing the keys (or IDs).
Hope this helps.
For being able to dynamically adding or removing from an array, you should use List, or ArrayList. Typical arrays don't provide delete or add at runtime, since they are fixed-size and if you want to control the procedure by handling the indices or other tricks, you'll probably end up in a messy and hard to maintain code.
On the other hand, Lists in java are dynamically sized and provide add(), remove(), get() and other convenient methods, which in my opinion best suits you.
You should use an ArrayList in order to dynamically add and remove entries in your array.
Make your theEmployee array into an ArrayList by doing:
ArrayList<Employee> theEmployee = new ArrayList<Employee>();
You can add and remove by doing:
public boolean addEmployeeID(Employee employeeAdd){
return theEmployee.add(employeeAdd);
}
public Employee deleteEmployeeID(int employeeDelete){
return theEmployee.remove(employeeDelete)
}
I changed the return type of addEmployeeID to boolean because an ArrayList returns a boolean when you add an object.
For remove, int employeeDelete would be the index of the object in the array. When you remove an object, all the remaining objects get shifted to the left. So if you have an array [1,2,3] and you remove 2, it would become [1,3]. The indexes are moved.
You could also remove an object so this should work:
public boolean deleteEmployeeID(Employee employeeDelete){
return theEmployee.remove(employeeDelete)
}
Where employeeDelete is an Employee and the function returns a boolean.
Related
I have several arraylists which each contain player data for a specific team. Each object contains the following elements in order; Jersey Number, First Name, Last Name, Preferred Position, Goals, Assists. The user decides whether to view the data by goals or assists, and then the data is displayed in descending order. Goals and assists are both of int data type.
I will be able to display the data fine but what I am stuck on is how to sort the arrayList by one of these specific stats. Because the data from all the teams is in different arrayLists, and need to be sorted all together, do I need to combine the arrayLists into one master arrayList that will be sorted? As for the sorting, I have done a bit of research and it looks like I need to use a comparator? Could someone provide some assistance with this because I have never used these before and am quite lost. Examples would be great.
I have attached a few code snippets to hopefully provide some clarity.
ArrayList <blackTeam> blackTeam = new ArrayList <blackTeam>();
ArrayList <blueTeam> blueTeam = new ArrayList <blueTeam>();
ArrayList <greenTeam> greenTeam = new ArrayList <greenTeam>();
ArrayList <orangeTeam> orangeTeam = new ArrayList <orangeTeam>();
ArrayList <redTeam> redTeam = new ArrayList <redTeam>();
ArrayList <yellowTeam> yellowTeam = new ArrayList <yellowTeam>();
private void displaystatButtonActionPerformed(java.awt.event.ActionEvent evt) {
//sort arrayList by goals/assists
}
EDIT:
This is how my classes are set up, as well as how data is added to them. Hopefully this clears up some questions.
//add data to database
black = new blackTeam(jerseyNum, firstName, lastName, prefPosition, goals, assists);
blackTeam.add(black);
class blackTeam {
int goals, assists;
String jerseyNum, firstName, lastName, prefPosition;
blackTeam (String _jerseyNum, String _firstName, String _lastName, String _prefPosition, int _goals, int _assists) {
jerseyNum = _jerseyNum;
firstName = _firstName;
lastName = _lastName;
prefPosition = _prefPosition;
goals = _goals;
assists = _assists;
}
}
I have one these classes for each team.
I suggest using Comparator on your object, let me assume it is Team
public class Team{
private int jerseyNumber;
private String lastName;
...
public int getJerseyNumber(){
return jerseyNumber;
}
}
If you want to sort based on jersey number, generate JeseryNumberComaparator:
import java.util.Comparator;
public class JeseryNumberComaparator implements Comparator {
#Override
public int compare(Team t1, Team t2) {
// descending order (ascending order would be:
// t1.getJerseyNumber()-t2.getJerseyNumber())
return t1.getJerseyNumber()-t2.getJerseyNumber()
}
}
It will sort your list based on jersey number by:
Collections.sort(blackTeam, new JerseyNumberComparator());
For sorting Collection in Descending order (other than their natural sort order), you have to define your own Comparator.
For sorting on a specific field individually (one at a time), you have to define separate Comparator implementation.
In your class, you can define two individual Comparators. Here is example code.
static final Comparator<Team> SORT_TEAM_BY_GOALS_DESCENDING = new Comparator<Team>(){
public int compare(Team t1, Team t2){
return t2.getGoals() - t1.getGoals();
}
}
static final Comparator<Team> SORT_TEAM_BY_ASSIST_DESCENDING = new Comparator<Team>(){
public int compare(Team t1, Team t2){
return t2.getAssist() - t1.getAssist();
}
}
Make sure that, normal sort is always natural order, in your case for int it is always Ascending. In order to have Descending order, you need to do t2 - t1. t1 - t2 will give you natural Ascending order.
Now in order to use this Comparator, just use following code.
Collections.sort(team, SORT_TEAM_BY_GOALS_DESCENDING);
or
Collections.sort(team, SORT_TEAM_BY_ASSIST_DESCENDING);
And off course, if all these different color List (i.e. blackTeam and so on) are only for specific team identified by color, than add one more field to your Team class called 'color` which will identify each player along with what team they belongs to.
As long as your 6 classes blackTeam to yellowTeam all descend from the same parent, ie. that they are declared like this:
public class blackTeam extends Team { ... }
then you can make a new ArrayList<Team> and add them all to it:
ArrayList<Team> all = new ArrayList<>();
all.addAll(blackTeam);
all.addAll(blueTeam);
all.addAll(yellowTeam);
// etc...
Then you can sort this list using an instance of Comparator<Team>. Since Java8, however, there's a much neater way to create a comparator using lambda expressions:
all.sort((a, b) -> a.getScore() - b.getScore()); // or whatever attribute you want to compare on
If you want to do it the old fashioned way instead, then you can create an anonymous class like this:
all.sort(new Comparator<Team>() {
#Override
public int compare(Team a, Team b) {
return a.getScore() - b.getScore();
}
});
They amount to the same thing, but the lambda based approach is a bit less wordy!
Note that i suspect you don't actually want to have 6 different classes for the different colours. Are you sure you have understood the role of a class properly?
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.
i need to fill an Array with different data types
InvoiceItem[] invoiceItems;
int test = 3;
int i = 0;
This needs to be in the Array:
InvoiceItem invoiceItem = new InvoiceItem();
invoiceItem.setItemType("TestItem");
invoiceItem.setArticleNo("TestItemID");
invoiceItem.setDescription("TestDescription");
invoiceItem.setQty(1);
invoiceItem.setPrice(new BigDecimal(20.00));
invoiceItem.setVat(new BigDecimal(5.0));
There is the possibility that there is more than one InvoiceItem (test=3), so it needs to be in a loop.
It has to be an Array, i need to pass it to another class which only accepts an Arrays.
How can i achieve this?
Edit: I will try to make my question more clear:
I need to know how to put these
invoiceItem.setItemType("TestItem");
invoiceItem.setArticleNo("TestItemID");
invoiceItem.setDescription("TestDescription");
invoiceItem.setQty(1);
invoiceItem.setPrice(new BigDecimal(20.00));
invoiceItem.setVat(new BigDecimal(5.0));
in an Array:
int countofInvoiceItem = 3; // there are 3 InvoiceItem
InvoiceItem[] invoiceItems = new InvoiceItem[countofInvoiceItem];
Where there can be more than one InvoiceItem.
Method looks like this:
public final ResponseCreateInvoice CreateInvoice
(Invoice Invoice, InvoiceItem[] InvoiceItems, Address DeliveryAddress, Address InvoiceAddress, String UserID, String Password)
(This is given and i can not change)
and returns
ResponseCreateInvoice inv = wsClient.createInvoice(invoice, invoiceItems, deliveryAddress, invoiceAddress, userID, password);
i am sort of new to Java (or arrays), so this may be an easy question, but i don't really get it. Also does it matter that there are Strings and Int, BigDecimal etc mixed together in an Array?
You just need to declare your array as an array of type T where T is a superclass of all the classes of the objects you want to fill it with. In the worst case, it would be Object but it's bad design 9 times out of 10.
I would recommend you to make a class that holds everything you need as follows:
public class YourClass{
int id;
double value;
String description;
//and so on
//create getters and setters
}
And you can use this class to pass array of objects to another class.
Put your objects of the class in the Array
For example
YourClass[] objects = new YourClass[SIZE];//define number of objects you need
And you can pass each and every objects separately or as a whole to another class.
And in your receiving class, you can have a constructor as:
public YourRecievingClass(YourClass[] object){
//and recieve here as you need; ask further if you need help here too
}
I think this is the best way to adopt though your question is not 100% clear
Based on your edit, your original question is off base. You do not want to create an array of different types but instead only want to create an array of one type and one type only, that being an array of InvoiceItems. You are confusing object properties with array items, and they are not one and the same. This code here:
invoiceItem.setItemType("TestItem");
invoiceItem.setArticleNo("TestItemID");
invoiceItem.setDescription("TestDescription");
invoiceItem.setQty(1);
invoiceItem.setPrice(new BigDecimal(20.00));
invoiceItem.setVat(new BigDecimal(5.0));
is where you are changing the properties of a single InvoiceItem.
It seems that your InvoiceItem class has String fields for item type, for article number, for description, an int field for quantity, a BigDecimal field for price and a BigDecimal field for VAT. And so your array would look simply like:
InvoiceItem[] invoiceItems = new InvoiceItem[ITEM_COUNT]; // where ITEM_COUNT is 3
You could use a for loop to then create your items:
for (int i = 0; i < invoiceItems.length; i++) {
invoiceItems[i] = new InvoiceItem();
}
And you could perhaps use the same for loop to fill in the properties of each InvoiceItem in the array:
for (int i = 0; i < invoiceItems.length; i++) {
invoiceItems[i] = new InvoiceItem();
invoiceItems[i].setItemType(???);
invoiceItems[i].setArticleNo(???);
invoiceItems[i].setDescription(???);
invoiceItems[i].setQty(???);
invoiceItems[i].setPrice(???);
invoiceItems[i].setVat(???);
}
But the unanswered question is, ... where do you get the data for each property of each InvoiceItem in the array? Is this information contained in a file? Is it inputted by the user? That is something you still need to tell us.
With which types of data? In general, you could use:
Object[] myArray;
All classes are subclasses of Object.
I'm trying to select and get values from customer objects. What I want to do is to enter a personal number like "702312" and search after the customer objects that has a data member personal number that are equal to "702312". And when I found it I want to get the rest of the values or change it's content. This is some code that creates the customer objects from the class Customer and then it's stored in a arraylist.
// create a new customer object and send personal number, name and account number to constructor
Customer customer = new Customer(personalNumber, name, newAccountNumber);
// create an arraylist to store customer objects
ArrayList<Customer> customerList = new ArrayList<Customer>();
// add the new customer object to arraylist that holds all customer objects
customerList.add(customer);
I have tried to reach the values like this, but it's not working, so I'm looking for some help?
// search for customer
for (Customer customer : customerList) {
if(customer.getAccountOwnerPersonalNumber() == "702312"){
System.out.println("OK!!!");
}
}
And instead of:
if(customer.getAccountOwnerPersonalNumber() == "702312")...
I have tried this:
if(customer.personalNumber == "702312")...
Finally I have also tested it like this:
for(int i=0;i<customerList.size();i++){
if(customerList.get(i).getAccountOwnerName() == "702312");
System.out.println("OK");
break;
}
I'm not sure if I'm doing right!? Help is preciated! Thanks!
You need to use the equals() method to compare objects like Strings by their internal value (otherwise they will only be compared by reference):
if (customer.getAccountOwnerPersonalNumber().equals("702312")) {
System.out.println("OK!!!");
}
or, better, if it can potentially return null:
if ("702312".equals(customer.getAccountOwnerPersonalNumber())) {
System.out.println("OK!!!");
}
or, if applicable, just make it a primitive like int, so that == will work the way you intended:
private int accountOwnerPersonalNumber;
with
if (customer.getAccountOwnerPersonalNumber() == 702312) {
System.out.println("OK!!!");
}
You want .equals():
if(customerList.get(i).getAccountOwnerName().equals("702312"))
customer.getAccountOwnerPersonalNumber() == "702312" this is wrong you cant compare them like that because it will compare their object type. you should do like this
if(customer.getAccountOwnerPersonalNumber().equals("702312"))
or this is better
if("702312".equals(customer.getAccountOwnerPersonalNumber()))
If the data that you query for is a String then in that case you have to use
equals()
So the entire things will turn out to be
if(customer.getAccountOwnerPersonalNumber().equals("702312")) {
System.out.println("OK!!!"); }
You're trying to compare customer.personalNumber to "702312" which is a String, so i conclude customer.personalNumber is a String too.
If I'm right, try String.equals() method instead of == operator. This is because this operator compares objects instead of value, which is what you want.
if(customer.getAccountOwnerPersonalNumber().equals("70312");)
...
I would suggest you use java.util.Collections binarySearch(...) method. It's of order O(log n)(in this case, since ArrayList implements RandomAccess) which is tons better than the O(n) order you get from doing your for loop.
You can make a separate comparator for the desired Customer fields(s) (in this case "personalNumber"):
private static class CustomerPersonalNumberComparator implements Comparator<Customer> {
#Override
public int compare(Customer o1, Customer o2) {
return o1.getPersonaNumber().compareTo(o2.getPersonaNumber());
}
}
Also, don't forget to sort your list according to your desired search criteria (the Comparator) before using binary search on it:
Collections.sort(customerList,new CustomerPersonalNumberComparator());
int desiredIndex = Collections.binarySearch(customerList, new Customer("658",null,null), new CustomerPersonalNumberComparator());
Customer desiredCustomer = desiredIndex == -1 ? null : customerList.get(desiredIndex);
And don't forget that the binary search returns the position inside our array for the desired element or -1 if nothing was found. So you must use that returned position to retrieve the desired instance from the list.