Modified LinkedList (2 integers per node) with ListIterator - java

I'm writing a code to save, delete and load a person's height and weight data. I have created 2 classes:
class Person {
private int height;
private int weight;
public Person(int h, int w) {
height = h;
weight = w;
}
public int getHeight() {
return height;
}
public int getWeight() {
return weight;
}
public String getValues() {
return ("Height "+height+" and weight "+weight);
}
}
class DataModified { //Problem in this class
private LinkedList<Person> lList;
private ListIterator<Person> lIter;
public DataModified() {
lList = new LinkedList<Person>();
lIter = lList.listIterator();
}
public void save(Person p) {
Person p1, p2; //p1: Data needed to be saved
p1 = new Person(p.getHeight(), p.getWeight()); //p2: Data already on the list
boolean alreadyExist = false;
lIter = lList.listIterator();
while(lIter.hasNext()) {
p2 = lIter.next();
if ((p2.getHeight() == p1.getHeight()) && (p2.getWeight() == p1.getWeight())) {
alreadyExist = true;
}
}
if(alreadyExist) {
System.out.println("Person: " + p1.getValues() + " had already been on the list.");
}
else {
lIter.add(p1);
System.out.println("Person: " + p1.getValues() + " is added to the list.");
}
}
public void delete(Person p) {
Person p3, p2; //p3: Data needed to be deleted
p3 = new Person(p.getHeight(), p.getWeight());
boolean alreadyExist = false;
lIter = lList.listIterator();
while(lIter.hasNext()) {
p2 = lIter.next();
if ((p2.getHeight() == p3.getHeight()) && (p2.getWeight() == p3.getWeight())) {
alreadyExist = true;
}
}
if(alreadyExist) {
lIter.remove();
System.out.println("Person: " + p3.getValues() + " is deleted from the list.");
}
else {
System.out.println("Person: " + p3.getValues() + " is not on the list.");
}
}
public void load() { //Problem
lIter = lList.listIterator();
Person p2;
for(int i = 1; lIter.hasNext(); i++){
p2 = lIter.next();
System.out.println("Person "+i+" has "+p2.getValues());
}
}
}
I had tested these 3 methods from class DataModified: I first save data from 3 persons, then delete 1 person and load the rest. However, the last method prints not the 2 persons on the list, but the person I have deleted before.
My question are:
What is wrong with my code? Why did the load() method work like that?
I noticed that after iterating, I can only modified the lIter. So are lList and lIter the same list or 2 separated lists? If they are not the same, how can I give lList the data from lIter?
Is there a way to stop the iteration of a list?

As others are pointing out, you definitely have a bug in your delete method. As written, if the target Person is found in the list, then the last Person in the list will be removed, not the target. You really need to be able to cut out of the while loop when you find the person and remove it immediately instead of continuing the loop.
To answer your questions:
What's wrong? The bug in delete that removes the wrong Person.
Are lList and lIter the same list? Conceptually yes, technically no. lList is the list itself, and lIter is the Iterator acting on that list. It's not a list itself. It's an Iterator. But the data it's working on is definitely the same list.
How to stop iteration? You have a few options. The easiest for how your code is currently written is a break statement. It stops execution of the current loop and resumes executing outside the block. In both your add and delete methods, it would make sense to break right after alreadyExist is set to true. Another option, suggested first by jiveturkey, is to add alreadyExist as a condition to the while loops. Then you'll only continue iterating if both there are more items to iterate over and alreadyExist hasn't yet been set to true. A third option would be to do the real work (i.e delete) as soon as you find the Person and then return from the method entirely.
Beyond that, some unsolicited general advice :)
You're comparing Person objects in multiple methods. Over time, this will get hard to maintain, so it would be better to define the comparison in one place. Java comes with an equals method for this. It's in every Object, but the default implementation won't help you, so you want to override it. In your case, you consider two distinct Person objects to be conceptually equal if their heights and weights are equal. So override the equals() method in Person to return true iff the height and weight are equal. See How to override equals method in java or http://users.csc.calpoly.edu/~gfisher/classes/102/info/howToOverrideEquals.html for some tips. If you override equals, you also need to override hashCode.
You're making copies of the Person parameters. The exact object being passed in is not the actual object being added or deleted from the list; the copy is. You could just use the paremeter. In the best case, you currently have an unnecessary performance hit (creating extra objects). In the worst case you'll hit bugs.
lIter is set both in the constructor and in every method. If you don't need to store its current state across method calls, then it should probably be just a local variable, used for a method and then discarded.
getValues() is currently just being used to make the object human-readable. That's a common problem, and the task given to toString(), also defined in Object and overridable in any class you write. All you'd need to do to take advantage of it is rename getValues to toString. Then you could just use it in a log message directly. Example below.
Here's how I would then rewrite delete, assuming a good equals method in Person, and getValues renamed to toString:
public void delete(Person p) {
boolean alreadyExist = false;
ListIterator definitelyNotLIter = lList.listIterator();
while(definitelyNotLIter.hasNext()) {
Person current = definitelyNotLIter.next();
if (p.equals(current)) {
alreadyExist = true;
definitelyNotLIter.remove();
// Option 1:
break; // next line to execute will be the if(alreadyExist) block
// Option 2:
// put your successful delete logging here
// return;
// and leave the failed delete logging outside the loop
// Option 3:
// Do nothing. The looping will continue, and you'd have a deleteAll method, where multiple items would get deleted if you managed to get duplicates in the list.
// You actually wouldn't need alreadyExist any more.
// I'd go with option 1, myself
}
}
if(alreadyExist) {
System.out.println("Person: " + p + " is deleted from the list."); // p.toString() will get called
}
else {
System.out.println("Person: " + p + " is not on the list."); // p.toString() will get called
}
}

In delete(), once you find your Person you set alreadyExist to true the first time you find someone and keep going. So once it's set, it's set for EVERYONE. If you find your Person in the list in position 1, you'll delete him, but then you'll delete the next person and so on. All of your while loops need to say.
while (!alreadyExists && lIter.hasNext()) {
p2 = lIter.next();
if ((p2.getHeight() == p1.getHeight()) && (p2.getWeight() == p1.getWeight())) {
alreadyExist = true;
lIter.remove();
}
}
// Delete the if/else code
You should probably get rid of the member variable:
private ListIterator<Person> lIter;

From Documentation:
void remove() Removes from the list the LAST element that was returned
by next() or previous()
But when you reach the required Person Object, you continue iteration the next Person Object.
What you need is to break the while loop once it finds the target object.
if ((p2.getHeight()==p3.getHeight())&&(p2.getWeight()==p3.getWeight())){
alreadyExist = true;
break;
}
Now the last element is the required Object, you can now use remove().
if(alreadyExist) {lIter.remove();}

The problem is in your delete method:
You loop through the entire list before removing anything. ListIterator.remove only deletes the last item returned by next(). You need to break when you find the item that already exists:
while(lIter.hasNext()) {
p2 = lIter.next();
if ((p2.getHeight() == p3.getHeight()) && (p2.getWeight() == p3.getWeight())) {
alreadyExist = true;
break;
}
}
Additionally, the way you are comparing Person objects should really be done in a equals() method, as described here.
Finally, your creation/use of an extra Person that is a duplicate of parameter p is entirely unnecessary here. Just use p instead of p1 (in save) and p3 (in delete).

Related

Duplicate Objects being stored in ArrayList with add method

I have two classes, one named Bird the other Runtime. The bird class creates birds - name, latin name. The Runtime class has 4 methods, only one is important for this question, that is the 'add' method. The add method when called upon needs to take input from the user that is name and latin name, these are saved into a string variable 'name' and 'latin name' and I call the Bird class constructor and pass in these string variables into its parameter and finally it is added to an ArrayList. However I get duplicate values, if I were to write the same bird twice.
I have tried to convert the ArrayList into a set and convert it back again into an ArrayList, i did this within the add method, this did not work. I suspect it is down to my poor understanding of how objects are stored in an ArrayList. I also created a getName method within the Bird class, so I can use list.get(i).getName, and if the name is equal to the one typed by the user, it prompts the user accordingly, if not it is added to my ArrayList. This also did not work. I also tried a for loop that would go through the ArrayList and an if statement would determine if the name typed by the user exists within the ArrayList, this also did not work, the attempt was early on so I can't remember exactly the error message, but the add method is called from within a while loop, and I think the error message was concurrent modification, I'm not entirely sure so please ignore that, my point is showing the various solutions I tried.
Below is The Bird class
public class Bird{
int obeservation = 0;
String name;
String latinName;
public Bird(String name, String latinName){
this.name = name;
this.latinName = latinName;
}
public void addBird(String name, String latinName){
this.name = name;
this.latinName = latinName;
}
public String getName(){
return this.name;
}
public String statistics(){
return this.name + " (" + this.latinName + ") : " +
this.obeservation + " observation";
}
}
Below is the Runtime class
public class Runtime {
ArrayList<Bird> birds = new ArrayList<Bird>();
Scanner scan = new Scanner(System.in);
public void scan() {
System.out.println("?");
String answer = scan.nextLine().trim();
while (!answer.equalsIgnoreCase("EXIT")) {
System.out.println("?");
answer = scan.nextLine().trim().toUpperCase();
if (answer.equalsIgnoreCase("ADD")) {
add();
} else if (answer.equalsIgnoreCase("OBSERVATION")) {
observation();
} else if (answer.equalsIgnoreCase("STATISTICS")) {
System.out.println("jhjh");//just to see if this is
working
statistics();
}
}
}
below is the add method, also what I've commented is the attempts,
currently the add method does not have an if statements to decide duplicates.
public void add() {
System.out.print("Name: ");
String name1 = scan.nextLine().trim().toUpperCase();
System.out.print("Latin Name: ");
String latinName1 = scan.nextLine().trim().toUpperCase();
birds.add(new Bird(name1, latinName1));
/*
Bird newBird = new Bird(name1, latinName1);
for (int i = 0; i < birds.size(); i++) {
if (birds.get(i).getName().equals(name)) {
System.out.println("Bird already exist");
return;
} else {
birds.add(newBird);
}
}
/*
* hBirds.addAll(birds); birds = new ArrayList<Bird>();
birds.addAll(hBirds);
*
* // Bird newBird = new Bird(name, latinName);
* /* if(birds.contains(name)){
* System.out.println("That name already exist");
* return;
* }else{
* birds.add(newBird(name, latinName));
*
* }
*/
}
The statistics method prints out the ArrayList, a foreach loop that goes through the ArrayList prints it out. The expected result if I input seagull twice should be one seagull value not two. How do i reject the duplicate?
You can have two approaches here:
First: Traverse through ArrayList, if you can't find the same bird, add it to ArrayList. It is a worse approach.
Second: Store birds inside HashSet. In this case, you need to override .hashCode() and .equals(Object obj) methods. It is a better approach.
Before talking about how to generate .hashCode() and .equals(Object obj) methods, I want to mention about .hashCode() method and HashSet<T>.
HashSet<T>s provide a unique set of the elements inside. To achieve this, .hashCode() method of a class is used. If you override .hashCode() method in any class, you can get the benefit of using HashSet<T>s. If you don't override this method, Java automatically returns the memory address of the object. That's why your HashSet<Bird> was including duplicate elements.
.hashCode() and .equals() methods can be generated by lots of IDEs. I copied and pasted your Bird class to Eclipse. By using Alt+Shift+S -> h for Eclipse or Alt+Insert -> equals() and hashCode() for IntelliJ, automatically generated the methods below:
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((latinName == null) ? 0 : latinName.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + obeservation;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Bird other = (Bird) obj;
if (latinName == null) {
if (other.latinName != null)
return false;
} else if (!latinName.equals(other.latinName))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (obeservation != other.obeservation)
return false;
return true;
}
If you add these methods(I encourage you to generate in your IDE) to Bird class, you can use HashSet<Bird>. To avoid duplicates, simply add all of your Bird objects into defined HashSet<Bird>. You don't need any other data structure or equality check to control if any two Bird type objects are equal.
You will just need to change your object collection from ArrayList<Bird> birds = new ArrayList<Bird>(); to Set<Bird> birds = new HashSet<>();.
Move the add out of the loop:
for (int i = 0; i < birds.size(); i++) {
if (birds.get(i).getName().equals(name1)) {
System.out.println("Bird already exist");
return;
}
}
birds.add(new Bird(name1, latinName1));

Why does .contains method on ArrayList of custom instances work?

I've been developing a small application for work, and I've come across something I can't figure out.
In the following code, I have an ArrayList of a Custom Class called 'Product' that contains data of type 'String'. I use the .contains method on this ArrayList to ensure it doesn't contain a certain String.
My IDE gives me the warning of 'Suspicious call to java.util.Collections.contains: Given object cannot contain instances of String (expected Product)'.
I completely understand the above message, because I'm comparing two different Types, so how can it ever evaluate correctly? I'm thinking it must be because the 'Product' class contains the data I want to compare, it is defaulting to using the toString method on the Product class (I override this in the Class) and comparing it with the String I want to compare it against.
It seems like JVM black magic to me.
private void createOrderListing(List<String[]> orderList)
{
//For each line of the order list file
for(String[] s : orderList)
{
if(s.length >= 28) //OrderLine should be of this length
{
if (!s[0].equalsIgnoreCase("ProductCode") && !s[0].isEmpty()) //Makes sure we're not including headers
{
//How does this bit work?
if(!productListing.contains(s[0]))
{
OrderLine order = new OrderLine();
//References product code of Product against Order Line, if match, then pack sizes and other basic fields ammended as appropriate
boolean productFound = false;
for (Product p : productListing)
{
if (s[0].contentEquals(p.getProductCode()))
{
order.initialAmendOrderLine(p.getProductCode(), p.getProductName(), p.getPackSize(), p.getProductType());
productFound = true;
}
}
if(productFound)
{
order.setOrderValues(s);
orderListing.add(order);
}
}
//System.out.println("\nOrder Product is: " + order.getProductName()+ "\nOrder Pack Size is: " + order.getInternalPackSize());
}
}
}
}
UPDATE
The reason this works as pointed out in the comments is that the block is always true (the .contains method is always false, the ! inverses this, hence true). Sorry for the confusion and pointing out my carelessness.
Here is an implementation of contains method in ArrayList that I have in OpenJDK:
public boolean contains(Object o) {
return indexOf(o) >= 0;
}
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
return -1;
}
Basically, there is nothing complex in it. It iterates through the all elements of your ArrayList and checks whether your given object is equal to the current one. If the condition is true then element exists in the list.
So let's imagine that you are passing String "SomeValue" to this method. Elements of ArrayList are iterated and following action is executed: "SomeValue".equals(elementData[i]) where elementData[i] is a product.
Since equals method of String class cannot compare String with a Product it returns false and as a result, you get false from contains method.
To fix this situation you can iterate over ArrayList manually and compare some Product's field with your string. E.g. you can implement following contains method:
public boolean contains(List<Product> products, String yourStringValue) {
for (Product p : products) {
if(p.getProductCode().equals(yourStringValue)){
return true;
}
}
return false;
}
productListing is a list of Product objects. Yet you are asking the list if it contains a specific String object -- which shouldn't ever happen.
What you should do is check if your Product#getProductCode is equal to your specific String. This can be acheived by using streams:
if(!productListing.contains(s[0])) // replace this
// with this
if (!productListing.stream().filter(o -> o.getProductCode().equals(s[0])).findFirst().isPresent())
What does this code do? It checks all your Product elements to find one whose myStringData attribute is equal to the String you're comparing.
since contains relays on equals implementation, when you do
if(!productListing.contains(s[0]))
you are asking the list OF ARRAYS OF STRINGS if its contains a String.
that will return always false because the type are different, so is not that is working at all, is that your condition will always return false

Java LinkedList contains() seems to fail

I'm trying to make a LinkedList containing the "best of" of an offspring in an evolutionary algorithm.
Therefore, I have my own custom add() method:
public boolean add(Virus v) {
if((this.size()< ConfigObject.getInstance().surviverPopulation //if the size of the new population is < surviverPopulation
|| v.getFitness() > this.getLast().getFitness()) //or the fitness is higher than that of the last member
&& v.getFitness() > 0.0 //and the fitness is higher than 0
&& !v.isDead() //and the virus is alive
&& !this.contains((Virus)v)) { //and it is not yet in the list
super.add(v); //add it normally
Collections.sort(this, new Comparator<Virus>() { //sort the list
//define parameter to sort by
#Override
public int compare(Virus virus1, Virus virus2) { //with custom comparator
if(virus1.getFitness() == virus2.getFitness()) {
return 0;
} else if (virus1.getFitness() > virus2.getFitness()) {
return -1;
} else {
return 1;
}
}
});
}
while(this.size() > 300) {
this.removeLast();
}
return true;
}
With this method, I get a LinkedList of limited size which is also sorted and only contains the "best" objects. (The rest of the LinkedList-class is unaltered).
However, when I use this class, something strange happens:
for(Virus parent : this.currentPopulation) { //for every virus in the current population
for(GraphNode child : parent.getChildren()){ //get all the children, and for each child
temp = (Virus) child;
if(!temp.isDead() && !newCurrentPopulation.contains(child)) { //try to add the child if it's not dead
newCurrentPopulation.add((Virus) child); //and not already in the list
} //(list only takes a maximum of <surviverPopulation>
} //and only the strongest ones, see declaration)
newCurrentPopulation.add(parent); //also try to add the parent to the list if
} //still alive
int j = 0;
for(Virus parent : this.currentPopulation) { //for every virus and its children in the current population
for(GraphNode child : parent.getChildren()){ //check if it made it into the new population
if(!newCurrentPopulation.contains((Virus) child)) {
toRemove.add((Virus) child); //if not, memorize to delete it later
}
}
if(!(newCurrentPopulation.contains((Virus) parent))); {
toRemove.add(parent); //do the same for the parent virus
}
}
It works quite fine for the children, but not for the parent. The debugging info shows that even though the parent (identifiable by an id) is in the newCurrentPopulation, it will be included into the toRemove list (where it's also identifiable by the same id).
Also, I did not override the equals-method for the Virus-class or any of its superclasses. I'm probably missing something quite obvious here but I can't see it.
It is something extremely obvious indeed: the last if-statement is followed by a semicolon and not the {}.
The contains method internally calls the equals method of Virus class.
The default equals method provided by the Object class uses == operator, which in your case returns false.
You have to override the equals method in Virus class and compare the objects with id.

Adding a Value to an Array

I have a method which needs to add the provided bank account to an array which I have created:
public boolean addAccount (BankAccount newAccount[]) {
if (numAccounts == 0) {
return false;
}
else {
return true;
for(int counter=0; counter<newAccount.length; counter++)
newAccount[counter] += accounts;
}
}
it is tested by this method:
public static boolean test5() {
System.out.println("Test5: add an account to a customer.");
BankAccount b = new BankAccount();
Customer c1 = new Customer("Alice", "Smith");
customerCounter ++;
if (!c1.addAccount(b))
return false;
return c1.toString().equals("Alice Smith, " + c1.getCustomerID() + "\n" + b.toString() + "\n");
}
However I am getting an error which eclipse does not have a solution for in this line:
newAccount[counter] += accounts;
First of all you need to improve the code quality. Re-design your function and data structure.
In the addAccount function, where did you derive/manipulate 'numAccounts'?
In method parameter, use List instead of array 'BankAccount newAccount[]'. Use like (List accounts). Then you can use accounts.add() method.
what is the definition of 'accounts'?
Do you really need to return anything from this method?
after return statement, no code will be executed. move 'return' statement as the last statement.
Paste the full code to get idea about overall structure.
If u just want to see how a new value can be added to an array then here it is...
int myArray[]={10,20,30};
int newNumber=200; //new value to be added
/*Size of an array doesn't change once it is initialized,so a new Array must be
created (with new Size )to add new values.*/
int newArray[]=new int[myArray.length+1];
//The newArray will have {0,0,0,0};
// Now copy all the data from previous array to new array.
for(int i=0;i<myArray.length;i++)
newArray[i]=myArray[i];
//Now the content of newArray is {10,20,30,0}
newArray[newArray.length-1]=newNumber;
//Now the final content of newArray is {10,20,30,200}.
Now,Having said that, I agree with #Turing85 and #Shafiul.With your above code,you will eventually get unreachable code and also Type Incompatible errors and yes,kindly redesign your code.

Adding elements to array in alphebetical order

I'm writing a program which adds telephone entries into a staff phone directory, I want to add the elements to the array in alphabetical order (using surnames) rather than adding the elements then calling Arrays.sort every time a new entry is added, as that would be less efficient. Here is some code I have so far, I'm not sure how to compare each element in the array with the following one and so forth.
public class ArrayDirectory implements Directory {
Entry [] directory = new Entry [50];
#Override
public void addEntry(String initials, String surname, int extension) {
//Entries are added here in alphabetical order
}
Here is my Entry class -
public class Entry {
private String initals,surname;
private int extention;
public Entry(String initals, String surname, int extention){
this.initals = initals;
this.surname = surname;
this.extention = extention;
}
public String getInitals(){
return initals;
}
public String getSurname(){
return surname;
}
public int getExtention(){
return extention;
}
}
Any suggestions, do I override compareTo? Thanks
edit - should have noted I have been asked to use an array. Sorry for the confusion.
Edit 2: updated my addEntry method and overriden compareTo in Entry -
public void addEntry(String initials, String surname, int extension) {
for (int i = 0; i < directory.length; i++) {
if (directory[i] != null) {
int y = directory[i].getSurname().compareTo(surname);
if (y == 1) {
int position = i;
break;
}
} else if (directory[i] == null) {
int position = i;
break;
}
}
}
And my compareTo method -
public int compareTo(Entry other) {
return this.surname.compareTo(other.getSurname());
}
I'm not sure how to shift the elements in the array to the right after I have found the correct position? Thank you for all of you help.
If you dont have to use an array then your using the wrong data structure.
No matter what path you need to implement Comparable:
public class Entry implements Comparable<Entry>{
..
#Override
public int compareTo(Entry other) {
// TODO Auto-generated method stub
return this.surname.compareTo(other.getSurname());
}
..
Consider using a SortedSet:
Set<Entry> map = new TreeSet<Entry>();
map.add(new Entry("JEH", "Hamlet", 123));
map.add(new Entry("AAC", "Adams", 123));
map.add(new Entry("FAM", "Monti", 321));
That will print in the desired order. If you must use an Array then you need to sort it upon insert.
You could make Entry comparable and implement the compareTo in it. But you don't really have to in this case because String is already comparable.
Since this is a homework, I think it will be best to just give you some suggestions on how to proceed, instead of handing you the code -
In your method you do not need to sort the array, you just need to insert it at the correct location in the array.
loop through the array starting at the first index
as you pass through each element in the array, you will have to check following two conditions
is the element null
is the surname of current element greater than surname-argument to the method
as soon as you find the element that satisfies any of the above conditions, record the index and break the loop
then, starting at that index shift the rest of elements to the right
and finally create a new instance of Entry for the provided arguments and set it at that index
Note: This doesn't take care of the situation where you are out of the space in the array.
Update:
I think you mixed up my answer and #David Wallace's answer. It wasn't my suggestion to implement compareTo. Also, it's great that you at least gave it a try and came back.
int position = -1; //declare the position outside (if declared inside, it's not visible outside the loop)
for (int i = 0; i < directory.length; i++) {
// position = i; just assign value of i inside the loop
}
//use the position after the loop
int j = position; // start at position
Entry temp = null; // temp will temporarily hold the entry at the next index
while(true) {
temp = directory[j + 1]; // since we need move entry at j to j+1, first we need save the entry at j+1
directory[j + 1] = directory[j]; // entry at j to j+1
if(temp == null) { // if the next entry is null, don't really need to move no more, so break
break;
}
}
// finally place new entry at index position
directory[position] = //the new Entry
Make Entry implement Comparable<Entry> and write the appropriate compareTo method in your Entry class. Then, in your insert method, you want to
Use Arrays.binarySearch to find the right place in the array to insert your the entry.
Use System.arraycopy to shift everything in the array that's after the appropriate location one place to the right.
Set the appropriate entry.
You'll want to check out the Javadoc for Arrays.binarySearch and System.arraycopy.
Firstly, never use arrays unless you absolutely have to. Use Collecctions instead - they are far easier to deal with and have support for lots of operations you commonly want to perform on groups of things.
In your case, a TreeSet would be a good choice. If you want to sort the entries by surname only in this usage (and not generally), you can pass a customer Comparator to the constructor:
Set<Entry> directory = new TreeSet<>(new Comparator<Entry>() {
#Override
public int compare(Entry o1, Entry o2) {
return o1.getSurname().compareTo(o2.getSurname());
}
});
If your always want to sort Entry objects using surname, have your Entry class implement Comparable<Entry> and move the code into the compareTo() method of the Entry class.

Categories

Resources