How do I add ArrayLists to an ArrayList? - java

So, I have already created an ArrayList<>, say Staff List.
private List<Staff> staffs = new ArrayList<Staff>();
public StaffFacade() {
staffs.add(new Staff("1", "James"));
staffs.add(new Staff("2", "Mike"));
staffs.add(new Staff("3", "Lina"));
staffs.add(new Staff("4", "John"));
}
public List<Staff> getStaffs() {
return staffs;
}
And I want to create another List that contains Staff List (by adding), so that I don't have to add the same Staff in StaffFacade?
I already created this BorrowFacade:
private List<Borrow> borrows = new ArrayList<Borrow>();
public BorrowFacade() {
borrows.add(new Borrow()) //How do I add this?
}
public List<Borrow> getBorrows() {
return borrows;
}
Referring to my question above, I don't know how to add new Staff List that has already been created.
This is the constructor for the Borrow List:
public Borrow(Date dueDate, Staff staff, Book books) {
this.dueDate = dueDate;
this.staff = staff;
this.books = books;
}
Of course, I put Date there because I wanted to add Date inside the List too.
MAJOR EDIT
Okay so let me try to put it this way. I have 4 classes which is StaffFacade, BorrowFacade, Borrow and Staff.
This is what I wrote inside StaffFacade:
public class StaffFacade {
private List<Staff> staffs = new ArrayList<Staff>();
public StaffFacade() {
staffs.add(new Staff("1", "James"));
staffs.add(new Staff("2", "Mike"));
staffs.add(new Staff("3", "Lina"));
staffs.add(new Staff("4", "John"));
}
public List<Staff> getStaffs() {
return staffs;
}
}
BorrowFacade:
public class BorrowFacade {
private List<Borrow> borrows = new ArrayList<Borrow>();
public BorrowFacade() {
borrows.add(staffsList);
}
public List<Borrow> getBorrows() {
return borrows;
}
}
Borrow (parts of it, the rest are just setters and getters)
public class Borrow {
String id;
Date dueDate;
Staff staff;
Book books;
public Borrow(String id, Date dueDate, Staff staff, Book books) {
this.id = id;
this.dueDate = dueDate;
this.staff = staff;
this.books = books;
}
Staff:
public class Staff{
String id, name;
public Staff(String id, String name) {
this.id = id;
this.name = name;
}
The problem is in BorrowFacade. I don't know how to add List that has been created in StaffFacade into BorrowFacade's List which is List<Borrow> borrows;
I'm very sorry for the confusion. If anything please ask me. I really want this program to work.

If you have a collection you can addAll(someOtherCollection); but I am not sure I fully understand your question: you refer to a 'constructor for the Borrow List' but you show a constructor for a Borrow class which is not a list.
You seem to be mixing up an instance of an individual class (e.g. Book) with a collection or plurality of that class: Book books (why is it plural? What are you trying to express?)
Edit:
Based on you comment, I think you're trying to understand how to construct the Borrow objects to be placed in the list.
The difference between constructed the Staff List is that you 'know' the staff ahead of time - albeit these are canned values.
The Borrow object seems to express a particular person borrowing a particular book due back on a certain date. If so, you need to have these details somewhere, for example from a database. The reason you're having trouble is you're trying to construct these objects in your Facade instead of just encapsulating ones that already exist.
public class Facade {
private List<Borrow> borrows = new ArrayList<Borrow>();
// Pass the items in to the constructor
public Facade(List<Borrow> borrows) {
this.borrows.addAll(borrows);
}
// You could call this externally in a loop to populate one by one
public void addBorrow(Borrow borrow) {
borrows.add(borrow);
}
}
To restate: your Staff and your Borrow objects have to come from somewhere, so if they're already in a collection, use addAll, if not, just iterate the list and call add. Don't construct the objects in your Facades.
Edit 2:
In response to your amended question, you can't do this. You're trying to add a list of a particulr object (Staff) in to a list of another type of object (Borrow). This is just inherently wrong. I don't quite know how else to say it. If you asked me to give you a List of my favourite Stack Overflow questions, would you expect to find my favourite Stack Overflow user in that list? This is the fundamental nature of type safety. Now, if you asked me to give you a list of my Favourite Things then it is perfectly reasonable to expect to find various types of things in there - Stack Overflow Questions, Wines, Foods, etc. because they would conceptually share a common Favourite parent class or interface.
To be frank, I think you neeed to (re-)read up on the basic nature of Java generics and type safety, but in pursuit of the almighty reputation, here goes:
Note: I'm using StaffMember and BorrowedItem as names here to try to illustrate the value of good naming conventions.
You seem to want a Facade class for reasons none of us understand. Okay, we can accept that. Your Facade class seems to contain a list of objects. You have created multiple classes to accomplish this, with no discernable difference between the two except which objects are listed inside. Generics to the rescue:
public class Facade<T> {
private List<T> list = new ArrayList<T>();
public Facade(List<T> existingList) {
list.addAll(existingList);
}
}
This facade holds a list of objects, meaning you can do this:
List<StaffMember> staffMembers= new ArrayList<StaffMember>();
// .. assume list is populated here
Facade<StaffMember> staffMembersFacade = new Facade<StaffMember>(staffMembers);
Likewise, with the same facade class:
List<BorrowedItem> borrowedItems = new ArrayList<BorrowedItem>();
// ... populate borrowed items
Facade<BorrowedItem> borrowedItemsFacade = new Facade<BorrowedItem<(borrowedItems);
But you aren't adding StaffMember objects to the borrowedItemsFacade. At least not directly - in your example a BorrowedItem has a Date and it also points to which StaffMember borrowed it.
So at this point you have two lists - a list of StaffMembers, and a list of BorrowedItems but you really have to ask yourself what purpose does this serve? Doesn't it make more sense for a single StaffMember to have a List<BorrowedItem> to keep track of all the items they borrowed?
class BorrowedItem {
Date dueDate;
StaffMember borrower;
}
class StaffMember {
String name;
List<BorrowedItem> borrowedItems;
}
Now this provides the opportunity to add a function to the StaffMember like this:
List<BorrowedItem> getOverdueItems() {
List<BorrowedItem> overdueItems = new ArrayList<BorrowedItem>();
Date today = getTodaysDate(); // Calendar.getInstance etc.
for (BorrowedItem borrowedItem : borrowedItems) {
Date dueDate = borrowedItem.getDueDate();
if (today.after(dueDate)) {
overdueItems.add(borrowedItem);
}
}
return overdueItems;
}
Do you see how you need to create meaningful relationships between these classes in order for there to be anything useful to happen?
Then you can add functions to let someone lend an item to another person, or take something from someone, etc.
So yeah, Collections.addAll is what you're looking for, I think.

Related

how to make ArrayList accessible by all JFrames and how to update it?

So I'm making a mock Starbucks app and I want that everytime a customer clicks the "Order" button, the product is added to an ArrayList and for this ArrayList to be accessed by all. I'm kind of confused where to insert the global ArrayList code...
This is code for my btnOrder:
private void btnOrderActionPerformed(java.awt.event.ActionEvent evt) {
String name = lblName.getText();
String size = cmbSize.getSelectedItem().toString();
int quantity = (int) spnrQuantity.getValue();
int price=0;
if (size.equals("Tall 12oz")) {
price = 170;
} else if (size.equals("Grande 16oz")) {
price = 180;
} else if (size.equals("Venti 20oz")) {
price = 190;
}
Global.list.add(new Object());
new Receipt(name, size, quantity, price).setVisible(true);
}
This is code for my Receipt frame which contains the JTable so I can display orders:
public class Receipt extends javax.swing.JFrame {
/**
* Creates new form Receipt
*/
public Receipt() {
initComponents();
}
String size, name;
int quantity, price;
public Receipt(String name, String size, int quantity, int price) {
initComponents();
this.name = name;
this.size = size;
this.quantity = quantity;
this.price = price;
addToTable();
}
void addToTable() {
DefaultTableModel table = (DefaultTableModel) tblCart.getModel();
Vector v = new Vector();
v.add(name);
v.add(size);
v.add(price);
v.add(quantity);
table.addRow(v);
}
And this is the code for the accessible ArrayList:
public class Global {
public static ArrayList<Object> list = new ArrayList<>();
private Global(){
}
}
Managing global state can be a nightmare, while you can use a singleton to solve the issue, it violates the Single responsibility principle. It also removes access control, allowing anyone to modify the list in whatever way they see fit without control.
Another solution is to use some kind of model, which can passed between the various components, if you make clever use of interfaces, you can control who can do what and when.
This is a core concept of Model-View-Controller and program to interface not implementation principle.
The basic idea is you would create a "model" which maintains the data you want to share, in this, primarily the items in the customer's order (and maybe the customer's name)
You would create an appropriate order and pass a reference of it to the "order" view, where it would be able to add/remove/update items to the model. When complete, the "controller" would then pass the same instance of the model to the "check-out" view, which would use this information to generate a bill (and possibly a payment information) and finally store the transaction
You would then be able to take the information from the model at the end and tell what has happened.
Because there are complex states you might need to control, you might need more than one model, for example, you could pass the "order" model to the "check-out" view, but it could create a "transaction" model, which wraps the "order" model
You can take use Singleton design pattern here. With Singletons, you can take advantage of Polymorphism which won't be possible with static objects.
enum Global {
INSTANCE;
private ArrayList<Object> list = new ArrayList<>();
public void add(Object obj) {
//custom validations (if any)
list.add(obj);
}
public Object get(int index) {
//check here for permissions, validations etc...
return list.get(index);
}
//other methods to access your shared objects
...
}
In this example, singleton pattern is implemented using ENUMs which ensures thread safety. You can also implement singleton using The ‘Inner Class’ Approach which is also thread safe.
Usage
private void btnOrderActionPerformed(java.awt.event.ActionEvent evt) {
...
Global.INSTANCE.add(new Object());
new Receipt(name, size, quantity, price).setVisible(true);
}
Difference between static class and singleton pattern?

Jodd DbOomQuery hint with collection

I'm using Jodd DbOom to manage my queries and it's really awesome. But right now I'm are facing an undocumented situation.
I have a query that returns a list of objects(A), and each A has a list of objects (B), and each B is joined with other objects(C, D, E, etc). The problem is that the class JoinHintResolver doesn't set the values C, D, E on the B objects. The B objects are set correctly on the A objects.
Below is a test method to reproduce the error. The other used classes(Girl, BadBoy) are from Jodd test packages.
public void testHintsList() {
Room room = new Room();
Girl girl = new Girl();
BadBoy badBoy = new BadBoy();
Object[] data = new Object[] { room, badBoy, girl };
JoinHintResolver jhr = new JoinHintResolver();
Object[] result = jhr.join(data, "room, room.boys, room.boys.girl");
assertEquals(1, result.length);
assertTrue(result[0] instanceof Room);
room = (Room) result[0];
badBoy = room.getBoys().get(0);
assertEquals(girl, badBoy.girl);
}
public class Room {
private Long id;
private List<BadBoy> boys;
public Room() {
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public List<BadBoy> getBoys() {
return boys;
}
public void setBoys(List<BadBoy> boys) {
this.boys = boys;
}
}
The documentation doesn't have any example like this, and Google neither. So I don't know if I did something wrong, or if Jodd wasn't prepared for this situation.
How could I set the hints so that Jodd would set the values correctly?
So the problem here is the fact that you have a collection of BadBoys in your Room. And the hint:
room.boys.girl
suggest they you want to inject a Girl instance into a collection. In java words, this is equivalent to:
getRoom().getBoys().setGirl(girl);
Obviously, since getBoys() returns a List, we can not set the girl property.
To test this what I've said, use the following hint instead:
room.boys[0].girl
This would inject the girl instance into the very first element of the list. Or, you can change your Room to have just a Boy property, instead of the list, and the original hint will work.
I hope this works for you :)
(see test)
EDIT
In this branch I have something that looks like a fix :) Now you can write something like:
select $C{room.*}, $C{room.boys:boy.*}, $C{room.boys.girl:girl.*}
from $T{Room room} join $T{Boy4 boy} on $room.id=$boy.roomId
join $T{Girl4 girl} on $boy.id=$girl.boyId
order by $room.id, $boy.id
And you can have the following model:
Room has list of Boy. Each Boy has one Girl assigned. When entityAware is on, this should work. Maybe you have time to test the branch?

How do I pass an object created in one class to another in java?

I'm trying to develop an online hotel booking system. I have the main class which takes input from the user such as their name, their payment information, and other data fields and makes a Reservation object using that information. I have another class called Room that has a list of Reservations for each Room object. The problem I am having is I can't figure out a way to add the Reservation object into the list in the Room object. Here is some of the code:
public class HotelReservationSystem
{
private Reservation reservation;
public void makeReservation(int checkIn, int checkOut)//Other parameters
{
reservation = new Reservation(checkIn, checkOut);
}
}
public class Room
{
private ArrayList<Reservation> reservations;
public void addReservation(//parameters?)
{
reservations.add(//parameter?);
}
}
I don't know how to get the new Reservation object to be passed as a parameter for the add method in the Room class.
I just can't wrap my head around it and was hoping for someone to help jog my thinking process.
Thanks for your help.
Let makeReservation return the created Reservation object:
public Reservation makeReservation(int checkIn, int checkOut)//Other parameters
{
reservation = new Reservation(checkIn, checkOut);
return reservation;
}
(You could also create a getter for reservation)
Then change your addReservation like this:
public void addReservation(Reservation res)
{
reservations.add(res);
}
And then just add it like this:
HotelReservationSystem hrs = new HotelReservationSystem();
Reservation res = hrs.makeReservation();
Room room = new Room();
room.addReservation(res);
However, you might want to rethink your model. Right now your HotelReservationSystem is creating a reservation and only saves that one, overwriting old ones. What happens if you create more than one? Also how can you get the reservations for a certain room given the HotelReservationSystem object? Just some things to think about...
I believe you must have tried this
public void addReservation(Reservation reservation)
{
reservations.add(reservation);
}
but the problem here is that your list reservations is null and will throw null pointer exception. So better initialize it at declaration. So change this
private ArrayList<Reservation> reservations;
to
private ArrayList<Reservation> reservations = new ArrayList<Reservation>();
And in your makeReservation method of Hotel class do this:
Room room = new Room();
room.addReservation(reservation);

Is simulating structs in Java a good way to go or not? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
Once I worked for a big tech company. We programed in Java. Guys there are amazingly smart and they like simulating struct in C/C++ in Java. To make myself clear, they advocate to create classes that act as "data holder":
public class BookInformation {
public final List<String> authors;
public final String bookTitle;
public BookInformation(List<String> authors, String bookTitle) {
this.authors = authors;
this.bookTitle = bookTitle;
}
#Override
public String toString() { ... }
#Override
public int hashCode() { ... }
#Override
public boolean equals(Object obj) { ... }
}
As we can see, the purpose of this class is simply holding data. Although we violate many enterprise programming rules, such as not exposing class fields directly and defensive copying, this kind of class does gain benefits such as concise coding. Instead of calling getters and setters, we can directly call field names.
The thing that annoys me is that this kind of class is hard to maintain and extend. It is hard to maintain because there is no way to make sure the states of the objects are legal. Business logic may say, a book must have a title and at least one author. But in real world, the objects can have empty title, null title, empty author list or null author list and we simply cannot control it. It is hard to extend. For example, what if the data source is changed to provide first name, last name separately for author name? I have to use two string lists instead of one. Worse, the data structure change affects and interface. Since I don't have a getAuthorNames() interface, I potentially have to change codes in many places.
I have to admit that the above scenarios are not happening. I have to admit that all code uses the class is under the control of the team so interface change doesn't sound that bad as writing for other teams/companies to use. So is it OK to have such coding standard even if we are using Java, a pure OO language, coding in enterprise level?
I know there probably isn't a "right" answer. I'd like to hear personal opinions. Speak loud on behalf of yourself!
EDIT:
OK. I should rephrase the core of my question: is it wise to sacrifice some of the textbook coding rules to gain simplicity? Will the sacrifice bit you later when the code base grows and team grows? Personal opinions matter, especially it is from wise persons and in many cases, there isn't right or wrong questions and we all just follow the convincing opinions. I am sorry Stackoverflow is designed only for right-and-wrong questions. In that case this question should just be closed.
I think there's a right answer: If it works for you, go for it. There are no style cops waiting to arrest you.
Know the rules and the reasons behind them. When you break them, understand the consequences. Have good justifications for what you do. Live with what happens.
For example, I don't think the rule to never expose data in public need be absolute - as long as you do it properly.
You need to realize that you did it wrong.
The fact that you made that List reference final just means that the reference can't be changed. The List that the reference refers to can have elements added and removed. You have to make it immutable to achieve what you want.
If you don't make it immutable, the changes you make to the reference you pass into the constructor will be reflected in your object. This would be true even if you made that reference private. You have to make a copy of the List you pass in to make your object's state truly independent. Same with other references to mutable types, like Date.
It works with String because it's immutable.
One more thing: that should be equals(), not Equals(). Case matters in Java.
public final class BookInformation {
public final List<String> authors;
public final String bookTitle;
public final Date publicationDate;
public BookInformation(List<String> authors, String bookTitle, Date publicationDate) {
this.authors = Collections.unmodifiableList((authors == null) ? new ArrayList<String>() : authors);
this.bookTitle = (StringUtils.isBlank(bookTitle) ? "" : bookTitle);
this.publicationDate = ((publicationDate == null) ? new Date() : new Date(publicationDate.getTime()));
}
#Override
public String toString() { ... }
#Override
public int hashCode() { ... }
#Override
public boolean equals(Object obj) { ... }
}
I find the standard getter/setters to be needlessly verbose sometimes but there are ways around this.
For example, you can use a getter or setters which is the same name as the fields and you can create operation methods which are more concise than accessing the fields directly.
e.g.
public class BookInformation {
private final Set<String> authors = new LinkedHashSet<>();
private final String bookTitle;
public BookInformation(List<String> authors, String bookTitle) {
assert authors != null;
assert bookTitle != null;
for(String author: authors) addAuthor(author);
this.bookTitle = bookTitle;
}
public String bookTitle() { return bookTitle; }
// get all the authors without needing a defensive copy.
// for(int i = 0, len = bookInfo.authorCount(); i < len; i++) {
// String name = bookInfo.author(i);
public int authorCount() { return authors.size(); }
public String author(int n) { return authors.get(n); }
public void addAuthor(String name) {
assert name != null
authors.add(name);
}
class AuthorCounter {
private final ConcurrentMap<String, AtomicInteger> authorCountMap =
new ConcurrentHashMap<>();
public void addAuthor(String name) {
authorCountMap.putIfAbsent(name, new AtomicInteger());
}
public void incrCountFor(String name) {
authorCountMap.get(name).incrementAndGet();
}
public int countForAuthor(String name) {
AtomicInteger ai = authorCountMap.get(name);
return ai == null ? 0 : ai.get();
}
}

Return two values from a java method

Let's say I have a method in java, which looks up a user in a database and returns their address and the team they are on.
I want to return both values from the method, and don't want to split the method in two because it involves a database call and splitting involves twice the number of calls.
Given typical concerns in a moderate to large software project, what's the best option?
whatGoesHere getUserInfo(String name) {
// query the DB
}
I know the question smells of duplication with existing ones, but each other question had some element that made it different enough from this example that I thought it was worth asking again.
you have some options.
The most OOP it will be create a class to encapsulate those 2 properties, something like that
private class UserInfo {
private Address address;
private Team team;
}
Or if you want a simple solution you can return an array of objects:
Object[] getUserInfo(String name) {
// query the DB
return new Object[]{address,team};
}
Or if you want to expose this method to some library you can have some interface that it will consume those properties, something like this:
class APIClass{
interface UserInfo{
public Address getAddress();
public Team getTeam();
}
UserInfo getUserInfo(String name) {
// query the DB
return new UserInfo(){
public Address getAddress(){ return address; }
public Team getTeam(){ return team; }
};
}
}
cant a map help , A MultivalueMap. Where the key is the user name and the 2 values are the adress and the team name. I am assuming both your Address and team are String variables, You can know more about Multivalue Map here
http://commons.apache.org/collections/apidocs/org/apache/commons/collections/map/MultiValueMap.html
http://apachecommonstipsandtricks.blogspot.in/2009/01/multi-value-map-values-are-list.html
First model your abstractions, relationships and multiplicity well (see an e.g. below). Then you can model tables accordingly. Once these two steps are performed you can either leverage JPA that can be configured to load your object graph or you write JDBC code and create the graph your self by running a SQL query with proper SQL JOINs.
A User has an Address
A Team can have 1 or more Users (and can a User play for more teams?)
You can return a String array with user name and group name in it . The method looks like :
public String[] getUserInfo(String name) {
String[] result = new String[2];
// query the DB
...
result[0] = userName;
result[1] = groupName;
return result;
}
A common solution to this kind of issue is to create a custom object with as many attributes as the values you want to return.
If you can't create a new class for this, you can use a Map<String, Object>, but this approach is not type-safe.
I thought Guava had a generic Pair class already, but I cannot find it. You can build your own using generics if you're on Java 1.5+.
public class Pair<X,Y>
{
public final X first;
public final Y second;
public Pair(X first, Y second) {
this.first = first;
this.second = second;
}
}
Feel free to make the fields private and add getters. :) Using it is easy:
return new Pair<Address,Team>(address, team);
Update
Apache Commons Lang has Pair. See this SO question for more options.

Categories