I have a Course class which has a method to add Items, which can be a note, an assignment, a URL, or just a generic item. All Items are kept in an ArrayList which the Course that created the list keeps up with. My question is from an item inside this ArrayList, how do I get the printLogger that I have attached to the course object in order to attach it to an item when the Item is created?
this from my Course:
public class Course {
private ArrayList<Item> items;
public PrintLogger p1 = null;
public Course(String code, String name) {
this.code = code;
this.name = name;
items = new ArrayList<>();
}
void add(Item item) {
items.add(item);
if (hasPrintLogger() == true) {
log(PrintLogger.INFORMATIONAL, "Adding " + item.toString());
}
}
And Im trying to have in the code that the assignment constructor runs a way to attach the same printLogger that is already on the course.
You could store a reference to the proper Course object in each of the items in the List.
You could also wrap the ArrayList class in your own class and add a field that points to the Course it belongs to if you need it to be a relationship between the List and the Course instead of between the items in the List and the Course.
You could also search each Course object in your system and check if it contains the List in question. However, this solution would scale badly.
Related
I am writing a mock hotel reservation system with two menus, employee and guest. Created rooms are stored in a master array called roomArray and added to a list view in the employee menu, and added to a list view in the guest menu. Rooms can be available or booked, however only available rooms are shown in the guest menu list view, so I might have 5 rooms but only 2 show in the guest menu list view. If the user clicks on the second one, I don't want to try and book the index 1 room in the main roomArray static ArrayList because they don’t match up.
For example, say in the employee list view I have three rooms, two of which are booked. In the guest list view, only the available rooms show up. So the list view on the right would show a selected index of 0, but the same index in the master roomArray is 1 for that same room. How can I make an intermediary of array list of available rooms that reference rooms in the master list?
Nathan
Since you are using JavaFX, you should use ObservableList for your rooms. Additionally, you would need to use FilteredList and FXCollections.observableArrayList(extractor).
This is how you can implement it:
public class Room {
public enum State {AVAILABLE, BOOKED}
private final ObjectProperty<State> state = new SimpleObjectProperty<>(AVAILABLE);
public final ObjectProperty<State> stateProperty() { return state; }
public final State getState() { return state.get(); }
public final void setState(final State value) { state.set(state); }
}
Main class:
private final ObservableList<Room> rooms;
public final ObservableList<Room> getRooms() { return rooms; }
private final ObservableList<Room> guestRooms;
public final ObservableList<Room> getGuestRooms() { return guestRooms; }
// Constructor
public MyClass() {
rooms = FXCollections.observableArrayList(room -> new Observable[] {room.stateProperty()});
guestRooms = rooms.filtered(room -> room.getState() == Room.State.AVAILABLE);
}
The guestRooms list is just a wrapper for rooms list, filtered with a Predicate. The filtered list will change according to the rooms list, but it will only react to changes to the list itself (add, remove, replace of elements). To make sure it responds to changes of the state of existing rooms, you need to use FXCollections.observableArrayList(extractor) overload. This overload allows you to control which property in each Room object would also trigger a ListChangeListener.Change, which would also causes the filtered list to update itself.
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.
I'm doing a project on web scraping using ArrayLists. When I scrape the info, it comes back as item [0] = pencil, item [1] = $1.50. I would like these items to be together, or if possible it would be even better if the prices and item each had their own id, but each was somehow linked together so that I could reference each one separately. Also, sometimes when scraping I get item [2] = paper, item [3] = $5.00, item [4] = wide bound college ruled, where item [4] represents an optional description that was included with the item that would need to be included in the ArrayList or in a separate ArrayList linked by ids as before. Any ideas are appreciated.
If you only need the name and the price, your best solution is to use a Map, works kind of like an ArrayList<T>, but instead of a single element you have a couple <Key,Value>, like <pencil, 1,50>.
If you need more than two values I would suggest to create your own class, for example:
public class Item {
private String name;
private double price;
private String description;
}
With all the extra methods you need, then declare your ArrayList like this;
ArrayList<Item> items = new ArrayList<>()
It would be better to make a class Item width variables for your name, price and description.
Then you can make an ArrayList to store all of your items.
You should model the object as a class, for example "item", and add each value as a variable of the class. For example:
public class item{
private String name;
private double price;
private String description; //If there's no description it could be null
// Constructor
...
// Getters and setters
...
}
You will need to format the price as a double.
I'm new to Java, coming from a C/C++ background. I'm trying to write a music player app for Android and I am working on a library scanning function. I want to have a hierarchical database of the format Artist -> Album -> Song where Artist has a name and a group of Albums, an Album has a name, year, and group of Songs, and a Song has a title, track number, and file location.
I created three classes to store this information:
public class libraryElementArtist
{
public String name;
public ArrayList<libraryElementAlbum> albums;
}
public class libraryElementAlbum
{
public String name;
public String year;
public ArrayList<libraryElementSong> songs;
}
public class libraryElementSong
{
public String name;
public int num;
public String filename;
}
The idea to fill them is simple - scan through each file and add its artist first, then album, then song. Each time it checks to make sure the artist/album does not already exist before creating a new one.
Essentially, I start off creating an ArrayList to store the artist information like this:
ArrayList<libraryElementArtist> libraryData = new ArrayList<libraryElementArtist>();
Then, to add an artist to the database:
libraryElementArtist newEntry = new libraryElementArtist();
newEntry.name = song_artist;
libraryData.add(newEntry);
And then to add an album:
libraryElementAlbum newEntry = new libraryElementAlbum();
newEntry.name = song_album;
libraryData.get(artistIndex).albums.add(newEntry);
where artistIndex is the index of the album's artist in the top-level artist array.
When I run this on the device and step through it in the debugger, the libraryElementArtist items are inserted into the libraryData array and their names are correctly filled in. However, the albums field is listed as null and trying to add albums does not fill in any data.
Sorry if this is a noob question, like I said I'm new to Java and I've searched and can't find what I'm looking for. Also, this is the way I'd do such a task in C++, not sure if it's the correct Java way.
I think is a Inheritance funda, So make your classes hierarchy as like (use of inheritance), So you have to make only one class which has all the derived propertied of its parent class, and make a ArrayList of that class only, So you don't have to make nested ArrayList. (If I am not wrong or if then please explain). :-)
Or generally make only one class which has all the properties, As you described above and use some getter,setter methods for that and using that class make your ArrayList.
create a custom class with getters and setters then create an arraylist as that datatype (your custom class)
List<customClass> foo = ArrayList<customClass>
same as the comment above but more info
All of the constructors should create (not just declare) the ArrayLists. Else they will be null. You can start them at a small size to save space. E.g
songs = new ArrayList(3);
I'm trying to delete an item from an array list by selecting it from a JList and clicking "Delete".
The code I have so far,
buttondeleteContact.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
if (contactList.getSelectedIndex() != -1) {
people.removeElementAt(contactList.getSelectedIndex());
People.remove(contactList.getSelectedIndex());
System.out.println(People);
}
});
I know some things are named poorly, but people (lower case p) is the name of my DefaultListModel and People (capital P) is the name of my ArrayList. Basically, I just want to delete a block of 4 lines from an array. So, the position in the array, and the 3 after it.
While List and ArrayList don't have a direct (and accessible) removeRange() method, the need for such a method is removed by providing the subList() method.
subList() provides a view into a part of the original List. The important part to notice is that modifying the returned List will also modify the original List. So to remove the elements with the indices index to index+3, you could do this:
myList.subList(index, index+4).clear();
Note that the second argument of subList() is exclusive, so this subList() call will return a List with a size of 4.
This is an odd requirement. Deleting 3 items after it? How are they related to each other? They must be somehow related to each other. It sounds like that you have a contact list which looks like this:
List<String> contacts = new ArrayList<String>();
contacts.add("John Doe");
contacts.add("Main street 1"); // His street.
contacts.add("New York"); // His city.
contacts.add("555 123 456 789"); // His phone.
// etc..
Is this true? Then you should really consider grouping the related elements into another real-world representing object. You could create a Javabean class Contact which look like this:
public class Contact {
private String name;
private String street;
private String city; // You could consider another Address class for street and city as well.
private String phone;
// Add/generate getters and setters.
public Contact() {
// Keep default constructor alive.
}
public Contact(String name, String street, String city, String phone) {
this.name = name;
this.street = street;
this.city = city;
this.phone = phone;
}
}
This way you just end up with
List<Contact> contacts = new ArrayList<Contact>();
contacts.add(new Contact("John Doe", "Main Street 1", "New York", "555 123 456 789"));
// etc..
so that you can just remove a single real Contact by index.
You could even make it a property of People:
public class People {
private List<Contact> contacts;
// +getter +setter
}
Try to think OO.
Joachim's answer gives a good way of removing directly from an ArrayList, but I suspect you really want to remove the range directly from the model. DefaultListModel has a removeRange method:
int index = contactList.getSelectedIndex();
people.removeRange(index, index + 4);
I would expect that to have the right behaviour, removing the items from the underlying list as well. Assuming that's the case, that would be the best way of doing it I suspect. Then again, I don't know Swing very well :)
Try,
people.subList(index, index+4).clear()