• Post Reply Bookmark Topic Watch Topic
  • New Topic

Using generic interfaces  RSS feed

 
Bartender
Posts: 726
23
Eclipse IDE Hibernate jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is how I tried to use generic interface and generic methods.
Output:
Person Information Before Sorting By Name:
Name: Hrithik Age: 40
Name: John Age: 20
Name: Anil Age: 50
Person Information After Sorting By Name Ascending:
Name: Anil Age: 50
Name: Hrithik Age: 40
Name: John Age: 20

******Sort By Age Ascending******
Person Information Before Sorting By Age:
Name: Anil Age: 50
Name: Hrithik Age: 40
Name: John Age: 20
Person Information After Sorting By Age Ascending:
Name: John Age: 20
Name: Hrithik Age: 40
Name: Anil Age: 50

Is this a way to use generic method and interface?
 
Saloon Keeper
Posts: 7993
143
  • Likes 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I wouldn't say this is correct. Your SortInfo interface defines a contract without the means to implement that contract reliably:

This is how your interface should be declared instead:

 
Ganesh Patekar
Bartender
Posts: 726
23
Eclipse IDE Hibernate jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:
Does HasNameAndAge means Person class in my example?
 
Stephan van Hulst
Saloon Keeper
Posts: 7993
143
  • Likes 2
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Person would be implementing HasNameAndAge, but so can Pet or anything else that has a name and an age.

However, it's even nicer to split up this interface into two separate traits:

This is what Person would then look like:

And a possible sorter interface could then look like this:
 
Ganesh Patekar
Bartender
Posts: 726
23
Eclipse IDE Hibernate jQuery MySQL Database Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is new code.
It works properly. Is this correct?
 
Sheriff
Posts: 4931
334
BSD
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ganesh Patekar wrote:It works properly. Is this correct?

There is a one side effect. Your original array personList gets altered after the sortByXXX gets invoked. That is not always correct, in your case I'd say incorrect as there are no records that you were aware of that. In case otherwise, since original array gets altered, you don't even need to return anything from the sort method. Check if that was your intention.
 
Stephan van Hulst
Saloon Keeper
Posts: 7993
143
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Besides what Liutauras mentioned, it looks correct. Here are some other pointers though:

  • Person is package-visible, but contains public members.
  • you should annotate toString() with @Override.
  • Person's fields can be null. You shouldn't allow this.
  • SortPersonInfo is a bad name. Either it's a verb, and class names shouldn't be verbs, or it's a noun, but it doesn't represent any kind of info. Call it something like PersonSorter.
  • SortPersonInfo can be final.
  • You're using a form of selection sort. Selection sort is an inefficient sorting method.
  • You duplicated your sorting code. Code duplication is bad.
  • GenericMethodDemo is public. Is this necessary?
  • GenericMethodDemo can be final.
  • personList can be final.
  • If Person has a constructor that initializes its fields from parameters, you can populate personList with an array initializer.
  • You don't have to call toString() inside println() argument list. The println() method automatically calls toString() if you pass it any old object.
  •  
    Ganesh Patekar
    Bartender
    Posts: 726
    23
    Eclipse IDE Hibernate jQuery MySQL Database Spring Tomcat Server
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Liutauras Vilda wrote:
    Ganesh Patekar wrote:It works properly. Is this correct?

    There is a one side effect. Your original array personList gets altered after the sortByXXX gets invoked. That is not always correct, in your case I'd say incorrect as there are no records that you were aware of that. In case otherwise, since original array gets altered, you don't even need to return anything from the sort method. Check if that was your intention.

    Ohh, Yes arrays are reference types so no need to return. Yes your are correct, actually I should not alter original array.(I don't have any condition but in general It is good to keep record of original)
    JLS 10.7.1 wrote: Arrays Are Cloneable (Only one dimensional (In multidimensional subarrays are shared))

    Here we have one dimensional array so I cloned original array into duplicatePersonList and used that cloned array for sorting. I also checked after sorting which alters duplicatePersonList but originalPersonList was not altered.

    Stephan van Hulst wrote:You're using a form of selection sort. Selection sort is an inefficient sorting method.

    Ohh I see, yes I'm going to revise all algorithms once again and will create new topic only for sorting algorithms soon( Later I will also sort them using comparators). It's been long time haven't gone through them but at this moment I think I'll keep this as It is because I'm brushing up my basic concepts of Java.

    Stephan van Hulst wrote:You duplicated your sorting code. Code duplication is bad.

    Are you saying duplicate code because of those two separate methods one for date of birth and other for name? Actually I wanted to have separate sorting one is based only on name and other on date of birth. I mean not  comparaing person on name and date of birth at a time. If I understood something else than what you meant then please let me know.

     
    Ganesh Patekar
    Bartender
    Posts: 726
    23
    Eclipse IDE Hibernate jQuery MySQL Database Spring Tomcat Server
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Here is latest code where I changed few names of fields, class and methods.
    I'm getting correct output. Any advice in above code?
     
    Liutauras Vilda
    Sheriff
    Posts: 4931
    334
    BSD
    • Likes 2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Ganesh Patekar wrote:
    In my opinion there isn't needed to write PersonSorter, especially if it sorts by name. As was mentioned earlier, if you'd sort Dog's array by their name, you'd end up implementing DogsSorter class, if got cows, you'd need to implement CowsSorter which basically would look similarly except sortByName method's parameter type.

    So what you could do, is to write a class in more general way so it would implement methods sort by name and age, and such example method signature would look as (but this time it takes interface as a parameter):
    As well similarly sorting by age. So, in that case you wouldn't care are the people or dogs or cats or cows, it would sort all entities who have names (implements interface HasName) and similarly with an age.

    Your code duplication appear in elements swapping. So, three lines in each of sorting method could be wrapped to a swapElements() method.
     
    Liutauras Vilda
    Sheriff
    Posts: 4931
    334
    BSD
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    That could look similarly to:
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 7993
    143
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Your sorting methods are only different in how they compare the elements. You can prevent code duplication by separating the comparison logic from the sorting logic:

    You can then call this generic sorting method like this:
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 7993
    143
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    The fun part is that you don't actually even have to implement the sort yourself this way. Check out what the method signature of Arrays.sort() is.
     
    Ganesh Patekar
    Bartender
    Posts: 726
    23
    Eclipse IDE Hibernate jQuery MySQL Database Spring Tomcat Server
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I apologize for being late, my internet connection was interrupted since last night 
    I created comparator for name and age and used with Arrays's sort method.
    Latest Code 1:
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 7993
    143
    • Likes 3
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    GenericMethodDemo has a public constructor. The class is package private.

    It's confusing to use 'List' in personList, because it's an array. Write personArray or just persons. The same goes for duplicatePersonList

    Why are you suffixing your variables with 'Obj1'? All reference variables refer to objects. It's unnecessary and clutters your code.

    Your variable names are cryptic because you are abbreviating them too much. Don't write nmAgeSrtrObj1; write nameAndAgeSorter, or just sorter. Similarly, don't write gnrcMthdDmObj1; write demo.

    NameAndAgeSorter implements a raw type. Never use raw types.

    The point above about abbreviating goes for getDOB() as well. There's no good reason to abbreviate it. There's plenty of room on modern monitors, the amount of time saved by writing the abbreviation is negligible but it makes code a lot less easy to read.

    SortByNameAndAge is a verb phrase. You should use noun phrases for type names. You should call it NameAndAgeSorter instead. The issue is that you already have a class named like that. How do the two relate? The concrete class gives default implementations for the methods declared in the interface. Such a class is called an adapter. Adapters are typically non-final, so that people can override the default behavior. This is what I propose:

    Your Person constructor now performs parameter checking, but you can still set a personName and personDOB to null through the setters. Since the Person class is final, you can do parameter checking in your setters, and then just call the setters from the constructor. However, I don't really see a good reason to be able to change a Person's name or age after you've constructed one. You can make Person immutable.

    personAge is a bad name for the parameter of setPersonAge(). A LocalDate does not represent an age, it represents a date.

    You can use String.format() to easily format strings with multiple variables:
     
    Bartender
    Posts: 10575
    66
    Eclipse IDE Hibernate Ubuntu
    • Likes 2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Ganesh Patekar wrote:I apologize for being late, my internet connection was interrupted since last night 
    I created comparator for name and age and used with Arrays's sort method.

    Yet another possibility is to use the fact that Java enums can implement interfaces. This allows you to create "named" Comparators for a class without having to worry about all that extra "generic" stuff (which I suspect is overkill in your case). Viz:
    and NOW you can sort an array of people with
      Arrays.sort(people, Person.Index.NAME);

    and if you're on version 8, you can use the new API to sort on any combination of "indices" you like, eg:
      Arrays.sort(people, Person.Index.NAME.thenComparing(
         Person.Index.AGE.reverse());


    HIH

    Winston

    PS: I think your AgeComparator is wrong. As DOB gets larger, your age decreases.
     
    Ganesh Patekar
    Bartender
    Posts: 726
    23
    Eclipse IDE Hibernate jQuery MySQL Database Spring Tomcat Server
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    @Stephan van Hulst I hope I made changes as you mentioned. I know I'm bit irking you all but please have look once again.

    Winston Gutkowski wrote:and if you're on version 8, you can use the new API to sort on any combination of "indices" you like, eg:
      Arrays.sort(people, Person.Index.NAME.thenComparing(
         Person.Index.AGE.reverse()); 

    That is stream API of Java 8 correct? I need to read about It before applyig here so for time being used sort with enum.
    Yes I've seen that sort of enum in JLS 8 Example 8.9.3-3. Enum Constants with Class Bodies.
    I created another College class just to see how It works using enum constants with class bodies.

    I came across an old thread about making class immutable here  --->link suggested to read Java theory and practice: To mutate or not to mutate? which was really informative so made changes according to that(I hope) in Person class.
    Latest Code 2:
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 7993
    143
    • Likes 2
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Great job!

    Now, I suppose the next thing to realize is that you're never actually using both sorting methods of NameAndAgeSorter in the same place. It was a nice interface to practice with generic type parameters that have disjoint type constraints, but in practice it's not very useful. Let's take this opportunity to introduce some more Java 8 features. We can make the solution more generic:

    You could then implement some standard sorting algorithms:

    If your HasAge trait looks like this:

    With some static imports, you could then sort an array of persons by age like so:
     
    Ganesh Patekar
    Bartender
    Posts: 726
    23
    Eclipse IDE Hibernate jQuery MySQL Database Spring Tomcat Server
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I created complete new code for Java 8 feature usage. I'm actually not acquainted with this new feature, yet to read and practice so just tried as per your code.
    package algorithms incorporates:

    package sortusage incorporates:

     
    Stephan van Hulst
    Saloon Keeper
    Posts: 7993
    143
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Great! The only qualms I have are with the declaration and definition of your sorting orders.

    The result of Comparator.comparing(HasAge::getDateOfBirth) is a comparator that will order items according to their date of birth. If you perform thenComparing(new DateOfBirthComparator()), you've created a comparator that will order items according to their date of birth TWICE. The second comparison is useless, so you can leave it out.

    Comparator.comparing(HasAge::getDateOfBirth) returns a comparator that does EXACTLY the same thing as DateOfBirthComparator. That means DateOfBirthComparator is redundant, you can delete it.

    The following points are a matter of personal taste:

    The name HasAge.REVERSE_ORDER is misleading. It implies the reverse of the natural order of things that have an age. But things that have an age don't necessarily have a natural order: What is the natural order of a Person? Why didn't you call it DESCENDING_ORDER_BY_DATEOFBIRTH?

    Before we do that though, I would move the ASCENDING/DESCENDING part to the end of the name. That way, these constants will appear close together in JavaDoc.

    Finally, I think ORDER_BY_DATEOFBIRTH is less intuitive to use than ORDER_BY_AGE, because people generally are more interested in sorting things by their age then by their date of birth. As Winston remarked earlier, an object's age has the reverse order of their date of birth.

    Putting it all together:
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 7993
    143
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Have a cow for your interest in the topic, and keeping up with it
     
    Liutauras Vilda
    Sheriff
    Posts: 4931
    334
    BSD
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Have one more cow. You definitely putted lots of effort.

    I learned from this topic too, as Java 8 features to me are unexplored field yet.
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 7993
    143
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I just realized I chastised you for using a type called SortByNameAndAge, while recommending types called HasName and HasAge.

    I should clarify that the HasSomething naming scheme is often used for interfaces that expose a simple property.

    A method like sortByName(HasName[] array) is not a simple property. It does not represent data that belongs to its type. A method like getName() is.
     
    Ganesh Patekar
    Bartender
    Posts: 726
    23
    Eclipse IDE Hibernate jQuery MySQL Database Spring Tomcat Server
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Internet problem episode kept continuing since last afternoon
    Oh I see, thank you for informing when an interface should be named like HasSomething. I'm getting lots of information need to document all major points.
    Wow this is the first time I'm being rewarded for doing something which I'm suppose to and benifits me,   thank both of you for cows. 

    Changes: removed redundant comparator, replaced order by date of birth by order by age, calculated age of person using date of birth and printed so we don't have to see their date of birth to check whether they are sorted correctly or not.

  • Code 1 with Java 8 feature:

  • package algorithms incorporates:


    package sortusage incorporates:


    Output:
    Before sorting:
    Person name: Hrithik; date of birth: 1987-07-31; Age: 29
    Person name: John; date of birth: 1980-01-15; Age: 36
    Person name: Anil; date of birth: 1997-09-11; Age: 18

    Order by age ascending:
    Person name: Anil; date of birth: 1997-09-11; Age: 18
    Person name: Hrithik; date of birth: 1987-07-31; Age: 29
    Person name: John; date of birth: 1980-01-15; Age: 36

    Order by age descending:
    Person name: John; date of birth: 1980-01-15; Age: 36
    Person name: Hrithik; date of birth: 1987-07-31; Age: 29
    Person name: Anil; date of birth: 1997-09-11; Age: 18

     
    Ganesh Patekar
    Bartender
    Posts: 726
    23
    Eclipse IDE Hibernate jQuery MySQL Database Spring Tomcat Server
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    I wrote a class having a method for Bubble sorting but not getting how to invoke It from enum here
    Should I invoke this method where throw new statement is(I mean replacing throw new)? in above BUBBLE_SORT element of enum? I'll put this BubbleSorter in package algorithms.
    I read how bubble sort works on Bubble Sort Wiki and tried to implement in code. Is It good code for bubble sorting Or should I improve?

    Bubble sort code 1:

     
    Stephan van Hulst
    Saloon Keeper
    Posts: 7993
    143
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Ganesh Patekar wrote:

    These comments are incorrect. These comparators don't compare by natural order. They compare by natural order of dates of birth.

    Ganesh Patekar wrote:

    You don't need to use Period.between(). HasAge already has a method you can use: getAgeAt().
     
    Stephan van Hulst
    Saloon Keeper
    Posts: 7993
    143
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Ganesh Patekar wrote:Should I invoke this method where throw new statement is(I mean replacing throw new)? in above BUBBLE_SORT element of enum? I'll put this BubbleSorter in package algorithms.

    Yes, you should replace the throw statement. However, you can't just call your sorting algorithm like that, because it sorts int arrays, and you want to sort T arrays.
     
    Ganesh Patekar
    Bartender
    Posts: 726
    23
    Eclipse IDE Hibernate jQuery MySQL Database Spring Tomcat Server
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Stephan van Hulst wrote:These comments are incorrect. These comparators don't compare by natural order. They compare by natural order of dates of birth.
    Yes I meant the same but didn't write by natural order of date of birth just to express common meaning of that.

    Stephan van Hulst wrote:You don't need to use Period.between(). HasAge already has a method you can use: getAgeAt().
    Ohh! I was wondering why we had default method in that interface.
    Stephan van Hulst wrote:Yes, you should replace the throw statement. However, you can't just call your sorting algorithm like that, because it sorts int arrays, and you want to sort T arrays.
    Ehh, didn't notice, yes It's T[] not int[]. Anyway I will try all these stuff later since I need to pay attention on basic core, once I finish those will definitely come to this again for sure. Because all these generic concepts are really interesting.
     
    Winston Gutkowski
    Bartender
    Posts: 10575
    66
    Eclipse IDE Hibernate Ubuntu
    • Likes 1
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Ganesh Patekar wrote:That is stream API of Java 8 correct?

    No, but the new Comparator API uses functional interfaces, which are a parallel development. In fact, Comparator itself IS a functional interface now.

    The only other thing I'd say is that different sort algorithms tend to have different strengths, so many modern routines use them in combination, based on things like size or "sortedness".

    Insertion sort, for example, works extremely well when a dataset is small or "mostly sorted" - far better than many supposedly "better" algorithms - but, of course, has a horrible worst case (O(n²). This makes it great as a "secondary algorithm" to use in conjunction with things like quicksort and mergesort.

    BTW, there's a relatively new "low-write" quadratic sort called Cycle sort that might interest you.

    Winston
     
    Ganesh Patekar
    Bartender
    Posts: 726
    23
    Eclipse IDE Hibernate jQuery MySQL Database Spring Tomcat Server
    • Mark post as helpful
    • send pies
    • Quote
    • Report post to moderator
    Winston Gutkowski wrote:No, but the new Comparator API uses functional interfaces, which are a parallel development. In fact, Comparator itself IS a functional interface now.
    Oh I see, yes I'm yet to study algorithms (Had done before but long time ago so need to revise) and their performance in different situations so I can understand which algorithm is good to use in which situation. Also about different list frameworks performance in different operations like search, delete etc. Thank you for Cycle sort link
     
    Consider Paul's rocket mass heater.
    • Post Reply Bookmark Topic Watch Topic
    • New Topic
    Boost this thread!