Comparing Linked-objects - java

I have some data from server which looks like this. Each row is an array so the data comes as an array of arrays:
net Person age
net Person height
net Address streetname
org Company name
org Company location
com School color
com School number
From left to right I loop through the array with two for loops and build a tree-like structure of each row(each element is a parent of its follower) like below. After each inner loop i add that particular tree(row tree-like) to the an ArrayList. So each object in the ArrayList is like a tree. As you can see below.
+net
Person
age
+net
Person
height
+net
Address
streetname
+org
Company
name
+org
Company
location
+com
School
color
+com
School
number
This is my main question
After I have added the first object to the ArrayList, I would like to compare the subsequent objects in order to prevent duplicates. As you can see "Person" and "Address" has the same parent "net" so I would like both to be under the same parent so that there will be a single "net". You can also see that "age" and "height" also has the same parent "Person", I want both to go under "Person". "Company" will be under a single "org" and their children "name" and "location" will be under "Company".
How can I compare them to achieve this behaviour?
I implemented the tree-like structure in a form like a linked list as you have spotted already.
//SUPER CLASS
public class Model {
protected String name;
protected Model parent = null;
protected ArrayList<Model> children;
public Model(String name ){
this.setName(name);
children = new ArrayList<Model>();
}
public void addChild(Model node) {
children.add(node);
}
public ArrayList<Model> getChildren() {
return children;
}
}
// SUBCLASSES
public class cPackage extends Model{
public cPackage() {
super();
}
}
public class cClass extends Model{
public cClass () {
super();
}
}
public class cMethod extends Model{
public cMethod () {
super();
}
}
Each element in a row belongs to one of these subclasses. Each level of a the tree belongs to the same class.
My main question now is, how can I compare them efficiently and bring the required objects under their appropriate parent?
Please I need your ideas. If there is a code also I will appreciate that you add it to your suggestions or point me there.
Thank you all.

If you override .equals and .hashCode, you could use a Set (HashSet implementation) to do an O(1) lookup. I would recommend, like mmyers, that you look into some data structures - Java has many of them that are designed for more specialied things.

Related

Differentiating Composition and Aggregation programmatically

I was going through below link to figure out differentiation between Composition and Aggregation.
https://www.geeksforgeeks.org/association-composition-aggregation-java/
I am able to understand that Composition implies a relationship where the child cannot exist independent of the parent while Aggregation implies a relationship where the child can exist independently of the parent. But not able to understand how can i differentiate that programmatically . Below is an example of Aggregation and Composition as given in link.In both cases the classes are same in structure except that Student and Department class has an extra variable "name" .As in Composition "child cannot exist independent of the parent ",but here I can create a separate object of Book and use it without adding it to Library.
Aggregation
// student class
class Student
{
String name;
int id ;
String dept;
Student(String name, int id, String dept)
{
this.name = name;
this.id = id;
this.dept = dept;
}
}
/* Department class contains list of student
Objects. It is associated with student
class through its Object(s). */
class Department
{
String name;
private List<Student> students;
Department(String name, List<Student> students)
{
this.name = name;
this.students = students;
}
public List<Student> getStudents()
{
return students;
}
}
Composition
class Book
{
public String title;
public String author;
Book(String title, String author)
{
this.title = title;
this.author = author;
}
}
// Libary class contains
// list of books.
class Library
{
// reference to refer to list of books.
private final List<Book> books;
Library (List<Book> books)
{
this.books = books;
}
public List<Book> getTotalBooksInLibrary()
{
return books;
}
}
As far as I can tell (and maybe somebody else can give a better answer), you can't evaluate if the relationship is aggregation or composition just by looking at Java code. It's the other way around.
First you create a conceptual model of the world. Libraries have books, and cars have wheels. Then you think - does it make sense for a book to exist without a library, or for a wheel to exist without a car, in the context I'm working in. So for example if you are writing a car racing game, you will have no use of wheels outside of cars. But if you are writing some auto-repair application, you will deal with wheels independently of some particular car.
So first you decide if you need aggregation or composition, and then implement it in your code. The implementation could be that object Car has List<Wheel> but you can't tell if it's composition or aggregation just from that. The key is that you interpret the code (implementation) based on your conceptual model and then use it according to that.
If it's composition, the usage it might have some restrictions:
No object other than Car will hold a reference to Wheel.
Wheel might even be a private or package-private class.
If Car is saved in database, when you delete it, you also automatically delete all of its Wheels.
But it's up to you to enforce these restrictions if you decide it's composition.
In the real world, a book can indeed exist in its own right without being owned by a library. But what if, instead, you had a LibraryBook class with fields like dateAcquired and currentBorrower? Using your design, you would still be able to create a LibraryBook instance without a library.
This is where languages like C++ can be more explicit about composition: in C++, an object can hold its parts by value. In Java, every object is handled by a pointer (OK, Java people don't call them pointers; they call them references instead.) This makes it more difficult to differentiate between composition and aggregation. In Java, you do it using careful design.
For example, we can make the LibraryBook class only instantiable through a method of Library:
class Library {
class LibraryBook {
private LibraryBook() {/*private constructor prevents independent instantiation*/}
}
LibraryBook createBook(String title, etc...);
}
Furthermore, if we make LibraryBook's mutator methods only accessible to the Library class, we can ensure that the book remains part of its owning library.

Linkend List copy constructor

I am having problems with the copy constructor of a Linkend List in Java.
The list I am trying to copy has a size of 3, when I use the copy constructor the list is empty.
When I try this with the clone method everything works great.
I have look a this for a quite a while and I get the feeling it is so obvious. I just
dont see it, here is the code.
public class Employee {
private String name;
private double salary;
public Employee(String name, double salary){
this.name = name;
this.salary = salary;
}
public void setname(String name){
this.name = name;
}
public void setsalary(double salary){
this.salary = salary;
}
public String getname(){
return this.name;
}
public double getsalary(){
return this.salary;
}
}
public class Main {
public static void main(String[] args) {
Employees employees = new Employees();
employees.add(new Employee("Employee1", 2500.00));
employees.add(new Employee("Employee2", 2400.00));
employees.add(new Employee("Employee3", 2000.00));
Employees employeesCopy2 = new Employees(employees);
Employees employeesCopy = (Employees) employees.clone();
System.out.println(employees.size());
System.out.println(employeesCopy2.size());
System.out.println(employeesCopy.size());
}
}
import java.util.LinkedList;
public class Employees extends LinkedList<Employee> {
private static final long serialVersionUID = 1L;
private LinkedList<Employee> employees;
public Employees(){
employees = new LinkedList<Employee>();
}
public Employees(Employees w){
employees = new LinkedList<Employee>(w);
}
public void addWerknemer(Employee w){
employees.add(w);
}
}
EDIT
This is homework, but when I wanted to add the tag is showed that the tag was no longer is use.
I think this:
public class Employees extends LinkedList<Employee> {
private LinkedList<Employee> employees;
will create a world of confusion. You're both extending a list, and within that class you're maintaining a separate list. When you call addWerknemer() you add to the inner list. What happens when you call get() ? Since you've not overridden this, you're calling get() on the base class, and that's a different list!
Without inspecting the rest of your code, I suspect this is a fundamental source of problems.
You have two choices:
Employees extends List
Employees contains a List
I would prefer the second. You can change the underlying collection (e.g. a Set, perhaps a Map for better lookup performance) and not change the exposed interface.
You are extending LinkedList, but also have a LinkedList inside that extension. Initially you use the add method to add Employee instances, so they get added to the Employees list itself, but when you use the copy constructor, you copy those employees to the employees field inside your Employees class.
When you call the size() method, it will use the LinkedList of the Employees object itself, so in the first list it is 3, but on the second it is 0 as now the employees are in the contained list and not in the object itself.
In this case you probably should not extend LinkedList. Or if you do, then don't use a separate field like employees which also contains a LinkedList.
Your confusion comes from the fact, that Employees both is a list and contains a list. When you use
employees.add(new Employee("Employee1", 2500.00));
you add the employee to the outer list. When you use
employees.addWerknemer(new Employee("Employee1", 2500.00));
you add the employee to the inner list. Since you have overwritten the constructor Employees(Employees es), this will not clone the outer list, but only the inner. And since you haven't overwritten clone(), it will clone the outer list, but not the inner. This is rather messy and also most probably not intended by you. I therefore propose one of the following changes:
1. [Preferred] Employees only contains a list and not extends one
Skip the extends LinkedList<Employee> and only work with an internal list. You will have to use your method addWerknemer(Employee emp) to add to your list (or change it's name to add). You will have to implement size and clone as well as other methods that you wish to use. If you want to be really clean about this, you can even make the class implement List or implement Collection or so. This way you can still treat your class as a java.util.Collection. I don't think that this would be neccessary in your case though. Also you would need to implement all of the interfaces methods (there are many). An example implementation would look like this. You still have to implement size, etc.
public class Employees /*implements List<Employees>*/ {
private static final long serialVersionUID = 1L;
private LinkedList<Employee> employees;
public Employees(){
employees = new LinkedList<Employee>();
}
public Employees(Employees w){
employees = new LinkedList<Employee>(w);
}
public void add(Employee w){
employees.add(w);
}
public Employees clone() {
return employees.clone();
}
// add more methods as you need them (like remove, get, size, etc)
}
2. Employees only extends LinkedList and doesn't contain one
Throw away your methods addWerknemer(Employee emp) and the copy constructor Employees(Employees) as well as your internal list. This way you will not overwrite the existing implementations of LinkedList. This approach is more or less useless because you basically just rename LinkedList to Employees and add/change nothing. Therefore I wouldn't recommend this approach.

Call a child class method from a parent class object

I have the following classes
class Person {
private String name;
void getName(){...}}
class Student extends Person{
String class;
void getClass(){...}
}
class Teacher extends Person{
String experience;
void getExperience(){...}
}
This is just a simplified version of my actual schema. Initially I don't know the type of person that needs to be created, so the function that handles the creation of these objects takes the general Person object as a parameter.
void calculate(Person p){...}
Now I want to access the methods of the child classes using this parent class object. I also need to access parent class methods from time to time so I CANNOT MAKE IT ABSTRACT.
I guess I simplified too much in the above example, so here goes , this is the actual structure.
class Question {
// private attributes
:
private QuestionOption option;
// getters and setters for private attributes
:
public QuestionOption getOption(){...}
}
class QuestionOption{
....
}
class ChoiceQuestionOption extends QuestionOption{
private boolean allowMultiple;
public boolean getMultiple(){...}
}
class Survey{
void renderSurvey(Question q) {
/*
Depending on the type of question (choice, dropdwn or other, I have to render
the question on the UI. The class that calls this doesnt have compile time
knowledge of the type of question that is going to be rendered. Each question
type has its own rendering function. If this is for choice , I need to access
its functions using q.
*/
if(q.getOption().getMultiple())
{...}
}
}
The if statement says "cannot find getMultiple for QuestionOption." OuestionOption has many more child classes that have different types of methods that are not common among the children (getMultiple is not common among the children)
NOTE: Though this is possible, it is not at all recommended as it kind of destroys the reason for inheritance. The best way would be to restructure your application design so that there are NO parent to child dependencies. A parent should not ever need to know its children or their capabilities.
However.. you should be able to do it like:
void calculate(Person p) {
((Student)p).method();
}
a safe way would be:
void calculate(Person p) {
if(p instanceof Student) ((Student)p).method();
}
A parent class should not have knowledge of child classes. You can implement a method calculate() and override it in every subclass:
class Person {
String name;
void getName(){...}
void calculate();
}
and then
class Student extends Person{
String class;
void getClass(){...}
#Override
void calculate() {
// do something with a Student
}
}
and
class Teacher extends Person{
String experience;
void getExperience(){...}
#Override
void calculate() {
// do something with a Teacher
}
}
By the way. Your statement about abstract classes is confusing. You can call methods defined in an abstract class, but of course only of instances of subclasses.
In your example you can make Person abstract and the use getName() on instanced of Student and Teacher.
Many of the answers here are suggesting implementing variant types using "Classical Object-Oriented Decomposition". That is, anything which might be needed on one of the variants has to be declared at the base of the hierarchy. I submit that this is a type-safe, but often very bad, approach. You either end up exposing all internal properties of all the different variants (most of which are "invalid" for each particular variant) or you end up cluttering the API of the hierarchy with tons of procedural methods (which means you have to recompile every time a new procedure is dreamed up).
I hesitate to do this, but here is a shameless plug for a blog post I wrote that outlines about 8 ways to do variant types in Java. They all suck, because Java sucks at variant types. So far the only JVM language that gets it right is Scala.
http://jazzjuice.blogspot.com/2010/10/6-things-i-hate-about-java-or-scala-is.html
The Scala creators actually wrote a paper about three of the eight ways. If I can track it down, I'll update this answer with a link.
UPDATE: found it here.
Why don't you just write an empty method in Person and override it in the children classes? And call it, when it needs to be:
void caluculate(Person p){
p.dotheCalculate();
}
This would mean you have to have the same method in both children classes, but i don't see why this would be a problem at all.
I had the same situation and I found a way around with a bit of engineering as follows - -
You have to have your method in parent class without any parameter and use - -
Class<? extends Person> cl = this.getClass(); // inside parent class
Now, with 'cl' you can access all child class fields with their name and initialized values by using - -
cl.getDeclaredFields(); cl.getField("myfield"); // and many more
In this situation your 'this' pointer will reference your child class object if you are calling parent method through your child class object.
Another thing you might need to use is Object obj = cl.newInstance();
Let me know if still you got stucked somewhere.
class Car extends Vehicle {
protected int numberOfSeats = 1;
public int getNumberOfSeats() {
return this.numberOfSeats;
}
public void printNumberOfSeats() {
// return this.numberOfSeats;
System.out.println(numberOfSeats);
}
}
//Parent class
class Vehicle {
protected String licensePlate = null;
public void setLicensePlate(String license) {
this.licensePlate = license;
System.out.println(licensePlate);
}
public static void main(String []args) {
Vehicle c = new Vehicle();
c.setLicensePlate("LASKF12341");
//Used downcasting to call the child method from the parent class.
//Downcasting = It’s the casting from a superclass to a subclass.
Vehicle d = new Car();
((Car) d).printNumberOfSeats();
}
}
One possible solution can be
class Survey{
void renderSurvey(Question q) {
/*
Depending on the type of question (choice, dropdwn or other, I have to render
the question on the UI. The class that calls this doesnt have compile time
knowledge of the type of question that is going to be rendered. Each question
type has its own rendering function. If this is for choice , I need to access
its functions using q.
*/
if(q.getOption() instanceof ChoiceQuestionOption)
{
ChoiceQuestionOption choiceQuestion = (ChoiceQuestionOption)q.getOption();
boolean result = choiceQuestion.getMultiple();
//do something with result......
}
}
}

representing hierarchical relationship

Can you suggest me "How can I represent the hierarchical relationship through java class?"
you are welcomed to suggest other techniques.
For instance, User specifies that
"Room" belongs-to "Floor" and "Floor" belongs-to "Center"
I want to represent this relationship as Java class, and later want to retrieve this relationship.
-Pankesh
What you're talking about is standard object composition
'Belongs-to' and 'contains' are rather similar here. So for example:
public class Center
{
private List<Floor> floors;
...
public List<Floor> getFloors()
{
return this.floors;
}
}
public class Floor
{
private List<Room> rooms
...
}
public class Room
{
private String roomNumber;
...
}

Java Linked List How to create a node that holds a string and an int?

I have been at this literally all day. I can create linked lists no problem and display/delete the data in them. My problem is though that I am not sure how to create a linked list of flights with each node including a reference to a linked list of passengers? This is an assignment in my advanced Algorithms class. I am drawing a blank here?
Create an object that holds a Passenger:
public class Passenger
{
private String name;
private int id;
}
Then give Flight a List of Passengers:
public class Flight
{
private List<Passenger> passengers;
}
Now you can have a List of Flights:
public class Schedule
{
private List<Flight> flights;
}
You needs lots more code in each. Be sure to override equals and hashCode for Passenger and Flight to make sure that they work properly.
Well, can't you just create a Flight class and a Passenger class?
class Flight {
private LinkedList<Passenger> passengers;
...
}
class Passenger {
...
}
LinkedList<Flight> flights = ...

Categories

Resources