Java linked list within a linked list - java

I am trying to do a little project I found online which is creating a Library Catalog of books and users.
I created 3 classes - Book, User, Manager. Manager has all the methods of checking out books, updating late fees, returning books etc. All these methods take place on a single user.
So if a user wants to check out a book, the manager calls the checkoutBook method on that user along with the book/s and checks them out. One problem I ran into was with late books. I want to be able to tie multiple late books to a single user. Using two separate lists here is too much of a hassle.
So I opted for a linked list within a linked list. But how exactly do I insert an element into the initial list and link it to the second list?
I.e. here is my code:
private LinkedList<User> userList = new LinkedList<User>();
private LinkedList<LinkedList<Book>> lateList = new LinkedList<LinkedList<Book>>();
userList is simply a list of whoever has checked out a book. In my lateList, I want to be able to insert a user within the first list, and a number of late books in the second list tied to that particular user.
How would I go about doing this? I tried to find some info online but it usually refers to placing a linked list within another linked list via the add method. Is there a good way of doing this or am I better off designing a separate class (or user a better data structure) to do this?

What I would do is, instead of having a linked list of linked lists of books, just have a linked list of late books within your user class. Then you can add methods to add/delete books from the list as you see fit. This approach makes more sense to me because the late books are essentially owned by the user, and this way you don't have to keep track of a user's late books by matching indices and tying them to another linked list.

Related

Adding products on the fly to order

I would like to add products to cart on the fly. This means the products to add are not stored in the database and doesn't have to. But when I take a look into the cart endpoint how items added to an order the class org.broadleafcommerce.core.order.service.call.OrderItemRequestDTO requires a product id.
So this means I've to override blCatalogService which would allow temporary products too? Is this all or did I forget something else to achieve the adding of products to the cart/order on the fly?
The OrderItem data model and services don't strictly require a SKU but many of the out of box examples do.
You should be able to override the CartEndpoint and instead of creating an OrderItemRequestDTO, create a NonDiscreteOrderItemRequestDTO.
The AddOrderItemActivity which is part of the workflow executed when an item is added checks for this type and will create an OrderItem instead of a DiscreteOrderItem or BundleOrderItem (both of which require a SKU).
Hope this helps,
Brian
Note : I work for Broadleaf

Need advice on most effective List to use, and the best practice to generate unique ids to each member

So I've got this school project, and I would really like to approach it with the best practices.
I need to make a list of customers for an insurance company. Each of these shall have a unique customer number, generated in ascending order.
Every customer can have zero to many insurances, also stored in seperate lists for each customer. Adding of insurances will happen more often than adding of customers.
Every customer can also have any numbers of claims. Every claim also has a unique id number.
If a customer cancels all insurances. All data on this customer will remain as history.
All data need to be stored via one of the file classes in the Java Standard Library. Databases are not allowed.
Actions such as showing of statistics will also be available.
Users of the program will be employees, with rights to edit every data field.
Questions:
What Collection class would be the most effective one to use? LinkedList, ArrayList, Hashmap or any other?
What file class would be the best one for saving the lists? ObjectOutputStream?
What is the best method of generating new unique ids for both customers and claims? As private fields in the customer list class? Information on the next unique id has to be restored every time the program exits and restarts.
Edit:
Not looking for help with any code. Just advice on the most common classes to use in a scenario like this.
What Collection class would be the most effective one to use?
LinkedList, ArrayList, Hashmap or any other?
Ans - LinkedList and ArrayList are types of List. HashMap is a type of Map.
What implementation of List you want to use depends on your requirement. If you are going to perform insertions and removals of elements at different points of a List frequently, then LinkedList makes more sense. It is more efficient at, say for example, removing an element in the middle of the List. Otherwise prefer to use ArrayList.
What is the best method of generating new unique ids for both
customers and claims? As private fields in the customer list class?
Information on the next unique id has to be restored every time the
program exits and restarts.
You may want to use a Singleton to generate IDs, and also persist them to a file.

List items ordering problem

I have a list of items and set of users. Users can re-order list items. Each user has his own view for the list, he can arrange the items in his own way. One item can be placed in different locations in list for different users. I've to track the item location for users in list item. Please give a suggestion to implement this. The size of the list is not constant. I'm using Java. My intension is I have to show the list for every user in their ordering format. Please Masters give me a suggestion.
You can keep an ordered list of, well, the order to retrieve items from your master list:
List<Foo> items = new ArrayList<Foo>();
// add stuff to items (say, 6 things)
Map<String,List<Integer>> userOrders = new HashMap<String,List<Integer>>();
userOrders.put("A", Arrays.asList(0,1,2,3,4,5)); // add user A's order
userOrders.put("B", Arrays.asList(5,4,3,2,1,0)); // add user B's order
// display for userA:
for(Integer i : userOrders.get("A")){
show(items.get(i)); // show the userA's i-th item
}
Here I'm also using a Map to hold the orders. Depending on your application you might use some other scheme to retrieve the user's custom ordering, but the principle will always be the same: if the user can have a custom order, you should store that ordering somewhere, and then iterate through the list of things based on that ordering (as shown above).
Also take care with the type of List you're using, calling get for random access on a LinkedList is substantially more costly than on an ArrayList.
Why don't you do a classic Object Oriented Design for this first, as suggested by glowcoder. Then you will have User class and Item class. User class will have a list of Item instances.
class User{
String userId;
List<Item> userItems;
}
A reverse structure would reflect in the database as well (User Table, Item Table and a User-Item Table with foreign key mappings to the first two tables). The Map of List solution suggested by Mark works, but is not the 'correct' approach in an object oriented language like Java.
You have one location that stores the actual list of items. Then each user gets their own model of the data. It is backed by the actual list, but model is more of a mapping between the actual indexes of each item and the display index the user has for the item. Then you have one viewer that can use the model to display the list in the GUI. As far as the viewer is concerned, the model is telling it the correct indexes. But the model allows for the conversion from displayed order to real order. As the user manipulates the list through the view, you update the index map and never touch the actual data.

Java program design question

I'm trying to come up with a simple way of organizing some objects, in terms of what classes to create. Let's say I'm trying to keep track of books. A book can fall under a number of different genres and subgenres. I want to be able to recognize a book as one book and yet have it fall under these different categories. I have a genre class which keeps track of all the subgenres, and a subgenre class which has all of the books in it. I want the book to know all of the genre and subgenres that it falls under. I also want to keep track of some statistics (reviews, comments, number of times read, etc.) based on genre and subgenre and then be able to aggregate them to get numbers for the entire book. In this way, a user could select a book and know, each genre/subgenre that the book belongs to, and soem statistics about that book for each category
What are some ideas for how I can design this?
My thought was to have each Book define a class called BookGroup, and the BookGroup would contain the Genre and Subgenre, along with any relevant information for that category (assuming that subgenres can only belong to one genre). Then in the Book class I would keep a set of bookgroups that the book belongs in. I can add up stats from all the different bookgroups. The only thing I don't like about this is that I feel like a BookGroup should contain Books, not the other way around.
Any other ideas?
Thanks!
Edit:
All you guys gave really good tips. I think for simplicity reasons, I might do something like this for now:
class Book
{
Genre myGenre;
SubGenre mySubGenre;
String myTitle;
}
class Library
{
Map<String,Set<Book>> allBooks = new HashMap<String,Set<Book>>();
//where allBooks contains a mapping from book title, to all of the book objects which actually represent the same book but may contain different information related to their specific genre/subgenre
}
I'd imagine you would want your classes to look something like this:
public class Book
{
String name;
List<Review> reviews;
Set<Genre> genres;
public Book(String name, Set<Genre> genres){}
}
public class Genre
{
String name;
Set<Book> books;
public Genre(String name, Set<Book> books){}
}
I am making an assumption here that you will be utilizing a database, in turn you would have a DAO to query on all known books that match a criteria and subsequently perform CRUD operations across the datasets. I feel a bit off by suggesting that the Genre constructor takes a Set of Book objects, but at the moment I can't think of another way to do this right now.
So, the problem is to do with inverse relationships, really. It's quite difficult to avoid this and maintain efficiency. A relational database sidesteps this issue by optimising in the background, using efficient query operations, and never storing the inverse relationship in the first place.
If you use a relational database in the background, you can create methods that get the book groups using a relational query without ever storing the information in Java.
I would just make two enums, one BookGenre = {scifi, novel, ...} and similar for subgenres. When creating a new Book object, add a reference to the Book object to some list which keeps track of all scifi book, etc ( i.e. make an EnumMap> which maps each genre to a list of books ); in this way you can easily access all the books of a genre.
There have been good suggestions from the other posters, but your original idea might work as well. The biggest problem for you, if I understand you correctly, appears to be one of naming: your 'BookGroup' is not really a grouping as such, but a descriptor of which group (genre/subgenre) it belongs to plus associated statistics. If you renamed it to e.g. 'BookGenreStatistics', the question of who contains what would go away.
I think you want collections pointing to each other. And when adding a book to a changre you would also add the changre to the book. Then just iterate as needed to obtain what you wanted. A changre and a sub changre should really be the same class, no need to have different classes here.
An alternative to this would be not to have references in a book to what changres it belongs to, instead if you need to know you would have to iterate through all changres and see if the book is in them. Depends on how many changres there are and how usual it is for a book to belong to a changre. Let's say if most changres have over half of all the books in them. The obvious third option is not to have books in changres, in that case you would have to iterate through the books to obtain the changres, the question is if most books belong to almost all changres, or if changres are unusual and only contain few books.
If you chose option number one, then a changre would be able to contain books and other changres, and a book would be able to contain changres but not other books. Sounds similar doesn't it? Well, it is, a changre and a book is the same thing, well, almost. The main difference is how you use them. Imagine a tree where the changres on top point down to subchangres and so forth, then they in turn point down to books who in turn point back up to the subchangres they're part of. Then in order to find all books in a changre for instance you would just have to traverse the tree from root up, except when you're at a book you stop. If a book can belong to several changres (yes, it can, right?), then you just need a loop variable in the book that's set when iterating and if the book is reached a second time you know because the variable has already been set.
For instance finding all the books in a changre:
1. Construct collection object that is to hold the result.
2. (in subclass changre) Iterate through all changres and books (they might be stored in the same collection object)
2. (same method as above, but in subclass book) Check if iteration field is set, if so just return, else add this to the result collection object.
3. Unset iteration field in all books of the result collection object to make it possible to redo from step one. (the alternative to having such an iteration field is of course use a collection that doesn't matter if you put in duplicates)
-Done, a book simply instead of iterating through the changres it has (like a changre does) knows that it has to add itself to the result.
Now that I think about it I think there's a tool that automatically generates code where you can specify things like a changre can have books and so on, and then to find all book reviews in a changre you can specify to traverse from the changre, pass at most one book on your path through the graph, and end in a review, and then agregate the results, and it generates code that does that. I don't remember the name or what language it was, but I think code like this can be generated from only a few lines, but of course writing it yourself shouldn't hurt either.

add to list without bringing whole list into memory

I have a web service that holds information for users. Each user has a list of items, possibly thousands. I want to add an item to the list without loading the entire list. Is there a list implementation that allows you to add elements to the list without bringing the entire list into memory?
A Doubly Linked List. By definition it's not necessary to traverse the list to add something to the end since it contains a pointer to the end.
the list is on a remote database. –
Lumpy
So the list is in a database, so it's not really a Java List? It's just a bunch of database rows? In that case why not just do an insert into the database to add another row?
INSERT INTO list VALUES 1, 2, 3;
Lazy proxies. You can use a JDK dynamic proxy (java.lang.reflect.Proxy) where you store only the information needed for retrieving the items from the database, not the items themselves. Only when calling the get(..), size(), contains(..) methods - fetch the data.
However I have a feeling that you are doing things the wrong way. Give more details about your implementation.
None that I know.
With middlewares such as Terracotta, some collections (such as maps) can be loaded on-demand and partially, but this doesn't exist as-is in the standart JDK.

Categories

Resources