java update all children in list - java

So Let's say I have a List of Persons that are related to each other and each contains their own family tree.
public class Person {
private int id;
private String name;
private List<Integer> ancestorIds;
private int parentId;
//getters and setters
}
so let's say I have the list as following:
List<Person> persons = new ArrayList<Person>();
persons.add(new Person(3,"grandpa", {}, null));
persons.add(new Person(4,"pa", {3,4},3));
persons.add(new Person(5,"uncle", {3,5},3));
persons.add(new Person(7,"me", {3,4,7},4));
But now we know that my grandpa his father was actually the one with id 1.. And i need to update the list.. How can I do this keeping in mind that I need to update it by line.. So first my grandpa.. Then taking the ancestorids list of him and give it to my pa and uncle (adding their ids as well). and then me taking the list of my pa and adding me. I think I need some recursive method for this.
Thanks in advance

If you make changes on this data structure it would be more flexible if you let each person point to it's direct ancestor only. And then build the tree on demand.
The way you mentioned in your question I would use if the tree don't gets changed.

Are you forced to use this representation? It would make more sense for the family tree to reference Persons, in particular, for the Person class to be defined as:
public class Person {
private int id;
private String name;
private List<Person> ancestors;
private int parentId;
//getters and setters
}
If done in this way, you don't need to update anything, except for your great grandfather. In fact, doing it line-by-line isn't a robust solution, since there's room for error (if you miss a single ID), and you should avoid this, to have good design. Even worse, unless you keep backpointers (i.e. have descendants as well as ancestors), there is no efficient way to update ancestors down the tree.

Related

How to use an object's class variables to identify an object in java?

I created a class and made 57 objects from it, each one has specific ID number.
Can I create a method which returns an object using an ID as the argument?
For example, assume the name of my class is Things and I made two object from it called apple and dog, they have IDs 1 and 2.
Things.java:
class Things {
private String name;
private int ID;
public Things(String name, int ID) {
this.name = name;
this.ID = ID;
}
}
Main.java:
class Main {
public static void main(String[] args) {
Things apple = new Things("apple", 1);
Things dog = new Things("dog", 2);
}
}
in this example I want to create a method in class "Things" which returns object apple if I use 1 as argument and object dog if I use 2 .
You cannot identify objects by a particular property unless you store it in a special repository
You can create a ThingRepository and can get specific Things by the id.
public class ThingRepository {
private Map<Integer, Things> thingsRepository = new HashMap<>();
public void addThing(int id, Things things) {
thingsRepository.put(id, things);
}
public Things getThingById(int id) {
return thingsRepository.get(id); //Can return null if not present
}
}
The addThing method need not explicitly take the id. If you add a getter to Things, then it can be simplified to
public void addThing(Things things) {
thingsRepository.put(things.getId(), things);
}
Couple of problems you need to address:
Each created Things object has to be added to this somehow (either the caller needs to add or there must be some other wrapper/factory that must do this).
Once a Things is not needed, it must be removed from the above map, else it can lead to memory leak.
Btw, shouldn't Things be named as just a Thing?
There are two aspects here:
you need some sort of data structure that remembers about created objects, and allows you to access them by id, for example a simple Map<Integer, Things>. Each time you create a new Things (should better be called Thing, shouldn't it?!), you go thatMap.put(newId, newThing).
if you want that data to "survive", you would have to somehow persist it (like writing data to a file, database, ...)
If you use Intellij for example press: alt + insert and choose getters/setter.
If not just write your own getters/setter ;).
Like here: https://docs.oracle.com/javaee/6/tutorial/doc/gjbbp.html
But basically if you want to look for Thing with particular Id you need to store somewhere them for example in ArrayList, then iterate through it and if your find element with that Id just return it.
1) Create new ArrayList
2) Iterate through
3) If you find Thing with Id you want, return it.

Multiple instance of class versus array Java

My question which of the following examples represents the right practice ?
What are the advantages and downsides of these approaches.
Is there another(right) way to achieve this?
Let's say I have class
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String print() {
return this.name;
}
}
And use of class like:
public static void main(String[] args) {
List<Person> people = new ArrayList<Person>();
people.add(new Person("Jane Doe"));
System.out.println(people.get(0).print());
}
And then another way to do this:
public class Persons {
private ArrayList<String> persons;
public Persons() {
persons = new ArrayList<String>();
}
public void putPerson(String name) {
persons.add(name);
}
public String print(int id) {
return this.persons.get(id);
}
}
And use of that:
public static void main(String[] args) {
Persons persons = new Persons();
persons.putPerson("John Doe");
System.out.println(persons.print(0));
}
EDIT:
Assume I have 10 000 of these persons.
Is there any downside to creating 10,000 instances of the class?
I would prefer the first way because there is a rare need to create a wrapper class for keeping a collection (like Persons -> Person). It makes sense if the class Persons gets renamed to a Company/Community, which contains a List of workers/persons and provides specific operations over this list.
public String showAllMembers() { ... }
public void notifyAllMembers() { ... }
Also, the second way breaks the Single responsibility principle. It shouldn't take care about printing a person, the class is responsible for adding/removing them. The Persons can provide to you a specific Person, then you have to call a method print() on a given instance:
Persons persons = ...;
persons.getMember(10).print();
Lets say i have 10 000 of these persons. Is there any downside to create 10 000 instance of class?
In any case, you will have to create 10000+ instances. Consider,
10000 Persons + a List
10000 Persons + a Persons + a List
The first one is more object-oriented than the second, which becomes apparent as soon as you start adding more properties to a person.
For example, consider adding a date of birth to a person. When you have class Person, you modify the class, and everyone who has access to it will be able to get it. You will also be passing the date of birth with the Person object, so any method that takes Person as a parameter will have access to that person's date of birth:
static void displayPerson(Person p) {
// Here, we can print both the name and the date of birth / age
}
public static void main(String[] args) {
...
displayPerson(people.get(0));
}
The second approach would require adding a parallel collection to the Persons class. All users of Persons would get access to date of birth, but unless a method takes the full collection as a parameter, it would have access to only the properties that the caller takes from the collection:
void displayPerson(String name) {
// Here, we have no access to person's date of birth
}
public static void main(String[] args) {
...
displayPerson(persons.print(0));
}
In Java, the first approach is the one to go with. It is more in accordance with the OOP way of doing things.
While there is nothing structurally wrong with the second, it doesn't follow the OOP architecture. You may do this kind of operation in C.
In the first approach, you create a Person class which defines what a person is - its properties, methods, etc. This is the object in Object oriented programming. When you need a Person, you then instantiate one and add it to a list of people.
In the second, you create a array, essentially. You can then create an instance of it and fill in the properties you want. However, I see the following drawbacks for this approach:
The object you're adding to the class doesn't exist anymore. Nowhere have you defined what a person is and what properties it has. These properties only exist in the values you add to the array. This can get very confusing and risky after a while.
No getters and setters. Every operation to retrieve a specific property and update it will result in very complex and redundant iterations on your array. In addition, your class can potentially have a very large number of properties, and every time you want to update a property, you'll have to be very careful to get the right index of that property in the array. It's a recipe for disaster.
Also, a putPerson method which just adds a value to the array? Cringy.
Short answer: don't do the second way, in Java, ever.
In my opinion example A is much easier to understand than B hence I would say code readability and maintainability wise it is better.
Reason is that for example B the persons structure actually involves composition of another structure ArrayList to accomplish generics which in example A, you have achieve it by declaring List<Person>.
Example B is also less flexible than A, because it is always a collection whereas example A you can simply use it as a Person and just plug it into different data structures available in Java. Example if you want to keep track of unique person, you can easily come out with a map that is keyed by <name, Person>, whereas example B would not be as clean because you will be doing something like <name, Persons> where each persons would only contain 1 person. Hence extensiblity wise may not be as great as the other one.
Also to me, A is more of the traditional way of doing object oriented because you are representing a real world object as a class whereas B is really just a wrapper of an object.
Obviously there can be a lot of arguments to this, but I'm happy with others input and critic about this answer.

Overrloading methods in Java interface [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
Is it right to overload method in Java interface like below. And then use the method required in your subclass? If not, is there a better way to do it, kindly suggest.
interface IEmployees{
public List<String> getEmployees(List<String> employees, List<String> departments);
public List<String> getEmployees(List<String> employees, String name);
}
class EmployeesByDept implements IEmployees{
public List<String> getEmployees(List<String> employees, List<String> departments){
// select employees belonging to depts in list and return.
}
public List<String> getEmployees(List<String> employees, String name){
throw new UnsupportedOperationException();
}
}
class EmployeesByName implements IEmployees{
public List<String> getEmployees(List<String> employees, List<String> departments){
throw new UnsupportedOperationException();
}
public List<String> getEmployees(List<String> employees, String name){
// select employees with name in list and return.
}
}
in my opinion overloading an interface this way is not a good idea, as this produces unnecessary/useless code at the implementing class.
I would therefore recommend to write 2 or 3 different interfaces like so
interface IEmployees {
}
interface IEmployeesByDept extends IEmployees {
public List<String> getEmployees(List<String> employees, List<String> departments);
}
interface IEmployeesByName extends IEmployees {
public List<String> getEmployees(List<String> employees, String name);
}
This Way you can cleanly implement the interface that matches your case.
Well, yes and no, it depends.
In general there are most certainly cases for it, where appropriate.
In your case though, probably not, and a lot of your issue comes down to more fundamental design problems. So just by reading your snippet it appears the possibilities are that an IEmployees is:
A set of all employees in a system (for example, all of the employees that work on a project or for a company), or
An arbitrary list of employees (includes 1 but also e.g. search results, etc., the semantic equivalent of a List<Employee>, or
A construct that has a list of employees associated with it (for example, a project, or an organization).
But you say:
it is actually an employee filter class. It will be inherited by other filter classes and will implement any one of the overloaded methods in the interface.
So your first minor problem is the interface name itself. IEmployees leaves a lot up in the air, but if you name it something more self-documenting and descriptive, e.g. IEmployeeFilter, then things start to come together a little more obviously.
So now you have a "filter", and it appears you are trying to have multiple separate filter strategies:
By department
By employee name
Possibly others
These are separate filters, and you state your interface defines a filter, and therefore these are more appropriately organized as two separate subclasses.
So first of all the interface should be what is common to all filters. How the filtering is done is not the common aspect. The filtering itself is. So consider:
interface IEmployeeFilter {
public List<String> getEmployees (List<String> employees);
}
Now you have a filter that makes sense, a single common method, and everything else falls into place, e.g.:
class EmployeeNameFilter implements IEmployeeFilter {
private String name;
public EmployeeNameFilter (String name) {
this.name = name;
}
#Override
public List<String> getEmployees (List<String> employees) {
return employees filtered appropriately
}
}
And:
class EmployeeDepartmentFilter implements IEmployeeFilter {
private List<String> departments;
public EmployeeDepartmentFilter (List<String> departments) {
departments = new ArrayList<String>(departments);
}
#Override
public List<String> getEmployees (List<String> employees) {
return employees filtered appropriately
}
}
Etc. Then when you're ready to use one the interface is always the same:
List<String> employees = ...;
IEmployeeFilter filter = new EmployeeNameFilter("bob"); // or...
// IEmployeeFilter filter = new EmployeeDepartmentFilter(...);
List<String> results = filter.getEmployees(employees); // <- interface always the same
Point is, interfaces exist as a tool to make a job easier. When you run into a situation where you have a bunch of classes implementing that interface but they all implement different parts of it, you're starting to defeat the purpose of an interface, and it's a good hint that there's a fundamental change that needs to be made in your design.
That is, a more general rule of thumb can be: If your interface is making your job harder, or making your code more complicated, you've done something wrong. Otherwise, you've done something right.
Hope that made sense.
Your use-case does not warrant the use of an Interface at all
An Interface represents a contract. You defined the contract as being able to fulfill two requirements. If you know you won't be able to provide both parts of the contract, do not use an interface at all.
Additionally, I strongly doubt you have alternative ways of getting these Employees Lists, another reason not to use interfaces.
Alternative solution
I am guessing your IEmployeesXXX classes have no state variable. This is a good indicator that the methods are utility methods which fetch and return a list of objects.
You should make it a classic Utility class, i.e. an abstract final class with static methods.
Here's an example using your own code, wich becomes much cleaner:
public abstract final class Employeesutility{
public static List<String> getEmployees(List<String> employees, List<String> departments){
// select employees belonging to depts in list and return.
}
public static List<String> getEmployees(List<String> employees, String name){
// select employees with name in list and return.
}
}
Notes going forward
I do not like Utility classes much, I would rather make an intermediate class with rich internal representation, and rich collections wich expose your proposed interface methods. But for your use case, this would probably mean duplicate the entire DB (guessing you have one), which would be stupid. Please consider it if ever you decide to create a true Employee class... which you will when your program becomes big enough.

Save a list of objects to ORMLite database

I am looking for a way to save a list of objects to the database with ORMLite and read upon this question: Best way to store several ArrayLists in ORMLite for ApplicationSettings
And the accepted answer makes sense to me:
public class YourClass {
#GeneratedId
private int id;
#ForeignCollectionField
private Collection<MyString> bunchOfStrings = new ArrayList<MyString>();
}
public class MyString{
#DatabaseField(canBeNull = true, foreign = true)
private YourClass yourClass;
#DatabaseField
private String text;
}
And the only thing that I don't understand is this line private Collection<MyString> bunchOfStrings = new ArrayList<MyString>(). Why do we save the ForeignCollectionField as Collection<MyString> instead of as ArrayList<MyString>? When working with the bunchOfStrings object above, do we always need to cast it to ArrayList<MyString>?
Why do we save the ForeignCollectionField as Collection
instead of as ArrayList?
That was design consideration, excerpt from doc
The field type of orders must be either ForeignCollection<T> or Collection<T> – no other
collections are supported because they are much heavier with many methods to support
When working with the bunchOfStrings object above, do we always need
to cast it to ArrayList
You dont have to initialize that field, Ormlite will do that. Hence, only available methods are ones present in Collection or ForeignCollection

Storing elements that have multiple elements

What is the best way to store an element that has multiple elements? As in a 6d array.
I have seen something along the lines of ArrayList(ArrayList(ArrayList(ArrayList))), but don't have a clue as to how or mostly why it would be configure as such or how to access the elements!
As an example, I want to create an array(list) that stores the following information:
house id, house number, street name, residents, owner first name, owner last name
I would like to be able to sort and search on anyone of the sub-elements in the main record element.
What I have done is create an arraylist that contains an arraylist for each of these. Basically I have a class called HouseArray that has a method called CreateArray. From my class GUI, I have
houses = new HouseArray();
houses.CreateArray();
In class
HouseArray, my method CreateArray has
ArrayList<Integer> entryID;
ArrayList<Integer> houseNum;
ArrayList<String> streetName;
ArrayList<Integer> residents;
ArrayList<String> firstName;
ArrayList<String> lastName;
entryID = new ArrayList();
houseNum = new ArrayList();
streetName = new ArrayList();
residents = new ArrayList();
firstName = new ArrayList();
lastName = new ArrayList();
and then I use an AddEntry method that puts data into each arraylist.
this.entryID.add(12345);
this.houseNum.add(9876);
this.streetName.add("My Street");
this.residents.add(4);
this.firstName.add("John");
this.lastName.add("Jones");
I am at a loss at how I would be able to sort this mess and keep the entries synchronized without manually writing a lot of coding to do it all. Also, I want to be able to sum the number of residents that live on a particular streetName or total the number of residents that live in houses owned firstName or lastName.
Am I on the right track or is there a better way to do this?
Teaching myself java, so not sure if this counts as homework.
As an example, I want to create an array(list) that stores the
following information:
house id, house number, street name, house color, owner first name,
owner last name
the best approach is to create a Class name it House and have these attributes as its state.
class House {
private long houseId;
private long hNo;
private String streetname;
private String color;
private String owner;
private String firstName;
public House(long houseId, long hNo, String streetName, String color, String owner, String firstName){
//initialize your instance variables here
}
public void setHouseId(long houseId){
this.houseId = houseId;
}
//do the same thing for reamining attributes
//getters and setters for all the attributes.
}
now, create a java.util.List which holds House Object.
List<house> houseList = new Arraylist<>();
//and populate the list with house objects.
House house1 = new House(123,223,"Bond Street", "Green","James Bond", "James");
list.add(house1);
This approach is more Object-Oriented way of doing things, as House represents an Object which has state and behaviour.However, if you want to sort your House elements in your arrayList you will have to override equals and hashcode methods.
I think another approach would be create House class with those properties.
Instantiate house object and add to arraylist. You may override equals and hashcode method to perform sorting.
Example:
class House{
int houseNum;
String street;
...
//get/set for above properties.
}
And add it to list:
House houseObj = new House();
list.add(houseObj);
Where exactly have you seen along the lines of ArrayList(ArrayList(ArrayList(ArrayList)))?? This looks wierd. Never have such kind of design..
If you want to store multiple fields, then create a custom class with all those fields, and have an ArrayList of that class.
For e.g: -
class House{
private int houseId;
private int houseNumber;
private String streetName;
private String owner;
private String firstName;
// Constructors
// Getters and Setters
}
And create an ArrayList of that class: -
List<House> myHouses = new ArrayList<House>();
then, to add an object to your list, just use normal add method: -
myHouses.add(new House(houseId, houseNumber, ....));
And to access elements: -
for (House myHouse: myHouses) {
System.out.println(myHouse.getHouseNumber());
}
I think you're not just new to Java. You're new object-oriented programming in general. Are you a student and this is some sort of homework? If it is, please tag it as such.
For your particular data, your class should be House.
public class House
{
int entryId;
int houseNum;
String streetName;
String houseColor;
String firstName;
String lastName;
}
Note that in my sample code above, I'm assuming you know enough of java to add the access modifiers like private, public, etc. and know enough about how to add getter and setter methods, (e.g. getEntryId(), setEntryId(int entryId), etc.).
If your objects are actually more complex, you might also be better off creating classes like Address, Person, etc.
Then with this class, you do create a list:
List<House> houses = new ArrayList<House>();
House myHouse = new House();
// insert whatever data you want into "myHouse"
houses.add( myHouse );
To sort the objects in a list, because it's in a List, it's part of Java's Collection Framework. You can use the Collections.sort() method to sort it. But first you need to understand how it works.
I would suggest you the following pages:
Object-Oriented Programming Concepts
Java Tutorial: Collections
Object Ordering
I am at a loss at how I would be able to sort this mess
First, others have already pointed out that you should create a House class to organize "this mess".
To sort it, implement the Comparator interface, e.g. (assuming your House class has a getEntryID method):
public class HouseIDComparator implements Comparator<House> {
#Override
int compare(House house1, House house2) {
return house1.getEntryID().compareTo(house2.getEntryID());
}
}
This comparator can be passed to Collections.sort(List<T>, Comparator<? super T>) for sorting. (Note that there is also a sort method with one argument, for lists of types that implement the Comparable interface. However, you probably do not want your House class to implement that, since it is not obvious on what basis houses should be compared, and you yourself might want to use several different ones.)
As for summing up values, the best way is to loop over all elements in the list and sum up manually.

Categories