Sort an array of objects alphabetically [duplicate] - java

This question already has answers here:
How can I sort a List alphabetically?
(15 answers)
Closed 9 years ago.
I have an array of objects and each objects has a given name and a surname.
These names are written to the object using methods getGivenName and getSurname.
I need to sort the elements in the array in alphabetical order by surname.
how can I do this?

Your comparator
class SampleComparator implements Comparator<YourObject> {
#Override
public int compare(YourObject o1, YourObject o2) {
return o1.getSurname().compareTo(o2.getSurname());
}
}
Your Sorting
Collections.sort(YourList, new SampleComparator())
if you need ignore case then use like
return o1.getSurname().compareToIgnoreCase(o2.getSurname());

Use List rather than using Array. Your class needs to implements Comparable interface.
Please see the code,
By Implementing Comparable interface
public class Person implements Comparable<Person>{
private String givenName;
private String surname;
public static void main(String[] args) {
Person person1 = new Person("a","b");
Person person2 = new Person("c","d");
Person person3 = new Person("e","f");
List<Person> personList = new ArrayList<Person>();
personList.add(person1);
personList.add(person2);
personList.add(person3);
Collections.sort(personList);
System.out.println(personList);
}
#Override
public String toString() {
return "WorkSheet [givenName=" + givenName + ", surname=" + surname
+ "]";
}
public Person() {
// TODO Auto-generated constructor stub
}
public Person(String givenName , String surname) {
this.givenName = givenName;
this.surname = surname;
}
public String getGivenName() {
return givenName;
}
public void setGivenName(String givenName) {
this.givenName = givenName;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
#Override
public int compareTo(Person o) {
// TODO Auto-generated method stub
return o.getSurname().compareTo(this.getSurname());
}
}
By Implementing Comaparator Interface
public class Person implements Comparator<Person>{
private String givenName;
private String surname;
public static void main(String[] args) {
Person person1 = new Person("a","b");
Person person2 = new Person("c","d");
Person person3 = new Person("e","f");
List<Person> personList = new ArrayList<Person>();
personList.add(person1);
personList.add(person2);
personList.add(person3);
Collections.sort(personList , new Person());
System.out.println(personList);
}
#Override
public String toString() {
return "WorkSheet [givenName=" + givenName + ", surname=" + surname
+ "]";
}
public Person() {
// TODO Auto-generated constructor stub
}
public Person(String givenName , String surname) {
this.givenName = givenName;
this.surname = surname;
}
public String getGivenName() {
return givenName;
}
public void setGivenName(String givenName) {
this.givenName = givenName;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
#Override
public int compare(Person o1, Person o2) {
// TODO Auto-generated method stub
return o2.getSurname().compareTo(o1.getSurname());
}
}

When sorting natural language texts, it's recommended to use a Collator and CollationKeys. The String.compareTo method mentioned by other answers will compare Strings based on the Unicode value of each character in the strings, which might not be what you want/ expect, depending on your input Strings and locale.
Note that I wrote some utility methods to help sorting natural language texts.
E.g. you coud try something like:
public class PersonLocalizer implements Localizer<Person> {
#Override
public String getDisplayString(Person person, Locale inLocale) {
return person.getSurname();
}
}
[...]
Localizables.sort(new PersonLocalizer (), persons);
Maven:
<dependency>
<groupId>org.softsmithy.lib</groupId>
<artifactId>softsmithy-lib-core</artifactId>
<version>0.3</version>
</dependency>

Related

How can i change "Curso" class to print in other class?

I got 2 classes
class Curso{
private String name;
public Curso(String nome){
this.name = nome;
}
public String getName(){
return this.name;
}
}
and
public class testaCurso{
public static void main(String[] args){
Course c1 = new Course("Computer Science");
c1.addDisciplina("AlgProgII");
c1.addDisciplina("SO");
c1.addDisciplina ("Grafos");
System.out.println(c1);
}
}
i gotta modify the Course class so that it can store the names of the Disciplina that make up the course and work for the test above with the output as shown. Consider that a course will not have a maximum of 50 subjects.
output:
Course: Computer Science,
Disciplinas:{ AlgProgII SO Grafos }
class Curso {
private String name;
// Add an list field containg the disciplinas
private final List<String> disciplinas = new ArrayList<>();
public Curso(String name){
this.name = name;
}
public String getName(){
return this.name;
}
// Add a `addDisciplina` method
public void addDisciplina(String name) {
disciplinas.add(name);
}
// Override the `toString` method
#Override
public String toString() {
return "Course: " + name + ", Disciplinas: + ", disciplinas;
}
}
We can implement toString() like the following:
public class Course {
private final String name;
private final List<String> disciplinas;
public Course(String name){
this.name = name;
this.disciplinas = new ArrayList<>();
}
public Course(String name, List<String> disciplinas){
this.name = name;
this.disciplinas = new ArrayList<>(disciplinas);
}
public void addDisciplinas(String discplina){
this.disciplinas.add(discplina);
}
#Override
public String toString() {
return "Course: " + name + ", Disciplinas: {" + disciplinas.stream().collect(Collectors.joining(" ")) +"}";
}
}
Usage:
Course course = new Course("Computer Science", Arrays.asList("AlgProgII", "SO", "Grafos"));
System.out.println(course);
Output:
Course: Computer Science, Disciplinas: {AlgProgII SO Grafos}

Generic linked list inside of linked list?

I am trying to write a program which stores information about a person in a linked list. I made a simple person class to store the name, age and addresses in the list. I would also like to store multiple addresses for EACH person, and a fact about the place in another linked list, inside the person class.
So for example, "Tara" can have a home address of "10 Central Ave" and a work address of "5 Willow street" etc. The problem is, I don't know how to have a linked list inside another.
My goal is to check whether the person's name is already on the list, and if so, add another address for them. (So that there is no repeats). I am a beginner and can really use some help.
public class Person {
private String name;
private int age;
public LinkedList <String> adresses;
public Person() {
name = "default";
age = 0;
adresses = new LinkedList<>();
}
public Person(String n, int a) {
name = n;
age = a;
}
public LinkedList<Adress> getAdresses() {
return adresses;
}
public void setAdresses(LinkedList<Adress> adresses) {
this.adresses = adresses;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String toString() {
return name+" "+age+" "+adresses;
}
}
public class Adress {
public String adress;
public String fact;
public Adress(String a, String f) {
adress = a;
fact = f;
}
public String getAdress() {
return adress;
}
public void setAdress(String adress) {
this.adress = adress;
}
public String getFact() {
return fact;
}
public void setFact(String fact) {
this.fact = fact;
}
}
public class Test {
public static void main(String[] args) {
Person Tara = new Person("Tara",35);
Person Judah = new Person("Judah",28);
Person Mark = new Person("Mark",45);
Person Seth = new Person("Seth",23);
LinkedList<Object> tester = new LinkedList<>();
tester.add(Tara);
tester.add(Judah);
tester.addLast(Mark);
tester.addLast(Seth);
System.out.println(tester);
}
}
How is about to use the next classic data structure for your project?
public class Person {
private String name
private int age;
public List<Address> addresses;
//...
}

Display multiple String items Java

I have a last Java homework task, this task is about employees,
my method should print employee's names and surnames, worked more than "n" years.
What I've done for now:
public class LastTask {
public static void main(String[] args) {
Employee employee1 = new Employee("Dobrobaba", "Irina", "Ivanovna",
"Moskva", 1900, 6);
Employee employee2 = new Employee("Shmal", "Anna", "Nikolaevna",
"Krasnodar", 2017, 8);
Employee employee3 = new Employee("Kerimova", "Niseimhalum", "Magomedmirzaevna",
"New-York", 2010, 3);
Employee employee4 = new Employee("Dobryden", "Yuri", "Viktorovich",
"Auckland", 2000, 11);
Employee employee5 = new Employee("Lopata", "Leonid", "Nikolaevich",
"Beijing", 2014, 11);
}
/**
* Prints employees' information, which have worked more than 'n' year(s) for now.
*
* #param n years quantity
* #return the String, contained surname, name, patronymic and address of the specific employee(s).
*/
public static String displayEmployees(int n) {
return null;
}
}
class Employee {
private String surname;
private String name;
private String patronymic;
private String address;
private int employmentYear;
private int employmentMonth;
Employee(String surname, String name, String patronymic, String address, int employmentYear, int employmentMonth) {
this.surname = surname;
this.name = name;
this.patronymic = patronymic;
this.address = address;
this.employmentYear = employmentYear;
this.employmentMonth = employmentMonth;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPatronymic() {
return patronymic;
}
public void setPatronymic(String patronymic) {
this.patronymic = patronymic;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getEmploymentYear() {
return employmentYear;
}
public void setEmploymentYear(int employmentYear) {
this.employmentYear = employmentYear;
}
public int getEmploymentMonth() {
return employmentMonth;
}
public void setEmploymentMonth(int employmentMonth) {
this.employmentMonth = employmentMonth;
}
}
I made a parametrised constructor for creating employees with multiple parameters, also made parameters encapsulated.
Have no clue what to do next, task says that I can use List/ArrayList, but after some time googling about it, I still can't understand how to implement a condition like if (employmentYear - currentYear >= n) then return employee1, employee4 for example.
Could you give me some tips?
Thank you for your attention.
You can create a static ArrayList and add those all employees to that ArrayList, and in displayEmployees method you can stream that list based on condition if employee EmploymentYear greater than n print details and add to another list so finally if you want you can just return count of employees or you can return List of employees also
public class LastTask {
static List<Employee> employee = new ArrayList<>();
public static void main(String[] args) {
Employee employee1 = new Employee("Dobrobaba", "Irina", "Ivanovna",
"Moskva", 1900, 6);
Employee employee2 = new Employee("Shmal", "Anna", "Nikolaevna",
"Krasnodar", 2017, 8);
Employee employee3 = new Employee("Kerimova", "Niseimhalum", "Magomedmirzaevna",
"New-York", 2010, 3);
Employee employee4 = new Employee("Dobryden", "Yuri", "Viktorovich",
"Auckland", 2000, 11);
Employee employee5 = new Employee("Lopata", "Leonid", "Nikolaevich",
"Beijing", 2014, 11);
employee.add(employee1);
employee.add(employee2);
employee.add(employee3);
employee.add(employee4);
employee.add(employee5);
}
/**
* Prints employees' information, which have worked more than 'n' year(s) for now.
*
* #param n years quantity
* #return the String, contained surname, name, patronymic and address of the specific employee(s).
*/
public static int displayEmployees(int n) {
List<Employee> finalList = new ArrayList<>();
employee.stream().forEach(emp->{
if(emp.getEmploymentYear()-Year.now().getValue()>=n) {
System.out.println("Employee Name : "+emp.getName()+" Sur Aame : "+emp.getSurname());
finalList.add(emp);
}
});
return finalList.size();
}
}
If you are looking for a way to find "worked more than 'n' years", this might help you.
Calendar.getInstance().get(Calendar.YEAR) - employmentYear >= n
Add a proper toString() method in the Employee class to get the desired output, apart from that I have used the filter() method from the Stream object to filter through the Employee objects. I am passing the number of years worked as an input parameter and calculating the years served in employment from the employmentYear field.
package com.company;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
import java.util.stream.Collectors;
public class LastTask {
private static List<Employee> listEmps;
public static void main(String[] args) {
Employee employee1 = new Employee("Dobrobaba", "Irina", "Ivanovna",
"Moskva", 1900, 6);
Employee employee2 = new Employee("Shmal", "Anna", "Nikolaevna",
"Krasnodar", 2017, 8);
Employee employee3 = new Employee("Kerimova", "Niseimhalum", "Magomedmirzaevna",
"New-York", 2010, 3);
Employee employee4 = new Employee("Dobryden", "Yuri", "Viktorovich",
"Auckland", 2000, 11);
Employee employee5 = new Employee("Lopata", "Leonid", "Nikolaevich",
"Beijing", 2014, 11);
listEmps = new ArrayList<>(Arrays.asList(employee1,employee2,employee3,employee4,employee5));
//display employee details of employees who worked more than 17 years.
displayEmployees(17);
}
/**
* Prints employees' information, which have worked more than 'n' year(s) for now.
*
* #param n years quantity
* #return the String, contained surname, name, patronymic and address of the specific employee(s).
*/
public static void displayEmployees(int n) {
int year = Calendar.getInstance().get(Calendar.YEAR);
listEmps.stream()
.filter(emp ->{
return year - emp.getEmploymentYear() > n;
})
.collect(Collectors.toList())
.forEach(System.out::println);
}
}
class Employee {
private String surname;
private String name;
private String patronymic;
private String address;
private int employmentYear;
private int employmentMonth;
Employee(String surname, String name, String patronymic, String address, int employmentYear, int employmentMonth) {
this.surname = surname;
this.name = name;
this.patronymic = patronymic;
this.address = address;
this.employmentYear = employmentYear;
this.employmentMonth = employmentMonth;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPatronymic() {
return patronymic;
}
public void setPatronymic(String patronymic) {
this.patronymic = patronymic;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getEmploymentYear() {
return employmentYear;
}
public void setEmploymentYear(int employmentYear) {
this.employmentYear = employmentYear;
}
public int getEmploymentMonth() {
return employmentMonth;
}
public void setEmploymentMonth(int employmentMonth) {
this.employmentMonth = employmentMonth;
}
#Override
public String toString(){
return "Employee details: " + this.name + this.surname + this.address + this.employmentYear;
}
}

How can I sort an arraylist based on the name and the Arraylist contains name with Initial of a person?

For Example:
I have [A John, B Adam, K Henry] added in an ArrayList.
I want the output as [B Adam, K Henry, A John]
Sorted based on the name, But when sorting it should not consider the initial of a person. How can I do this?
Use comparator that compares only the names:
List<String> list = Arrays.asList("A John", "B Adam", "K Henry");
list.sort(Comparator.comparing(s -> s.split(" ")[1]));
you can use compareTo() method.. first split the names using space split(" ") then save all names in string array use compareTo() for prev word and curr word..
Create a class Person for your persons and use a Comparator to sort the list.
Class for person:
public class Person {
private String surname;
private String forename;
public Person(String forename, String surname) {
this.surname = surname;
this.forename = forename;
}
public String getSurname() {
return surname;
}
public void setSurname(String surname) {
this.surname = surname;
}
public String getForename() {
return forename;
}
public void setForename(String forename) {
this.forename = forename;
}
}
Sorting:
#Test
public void testSortPersons() {
List<Person> people = Arrays.asList(new Person("John", "A"),
new Person("Adam", "B"),
new Person("Henry", "K"));
people.sort(Comparator.comparing(Person::getForename));
}
It would be generally a more robust approach to have a class containing the data of your persons instead of using Strings.
I strongly suggest to use a better object then String in your list.
In that case you can use a Comparator for sorting out your list, or make your object Comparable.
import java.util.ArrayList;
import java.util.Collections;
public class ComparatorExample {
static class Person implements Comparable<Person> {
private String initial;
private String surName;
public Person(final String initial, final String surName) {
this.initial = initial;
this.surName = surName;
}
public String getInitial() {
return initial;
}
public void setInitial(final String initial) {
this.initial = initial;
}
public String getSurName() {
return surName;
}
public void setSurName(final String surName) {
this.surName = surName;
}
#Override
public int compareTo(final Person o) {
return surName.compareTo(o.surName);
}
#Override
public String toString() {
return initial + ' ' + surName;
}
}
public static void main(String[] args) {
Person a = new Person("A", "John");
Person b = new Person("B", "Adam");
Person c = new Person("K", "Henry");
ArrayList<Person> list = new ArrayList<>();
list.add(a);
list.add(b);
list.add(c);
System.out.println(list);
Collections.sort(list);
System.out.println(list);
}
}

List iteration & setting values with Java 8 Streams API

I'm trying to understand how to use the Java 8 Streams API.
For example, I have these two classes:
public class User {
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
}
public class UserWithAge {
private String name;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
private int age;
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
}
I have a List<User> of ten users, and I want to convert this to a List<UserWithAge> of ten users with the same names and with a constant age (say, 27). How can I do that using the Java 8 Streams API (without loops, and without modifying the above classes)?
You could use the map() feature of the stream to convert each User instance in your list to a UserWithAge instance.
List<User> userList = ... // your list
List<UserWithAge> usersWithAgeList = userList.stream()
.map(user -> {
// create UserWithAge instance and copy user name
UserWithAge userWithAge = new UserWithAge();
userWithAge.setName(user.getName());
userWithAge.setAge(27);
return userWithAge;
})
.collect(Collectors.toList()); // return the UserWithAge's as a list
While you could do this, You should not do like this.
List<UserWithAge> userWithAgeList = new ArrayList<UserWithAge>();
userList.stream().forEach(user -> {
UserWithAge userWithAge = new UserWithAge();
userWithAge.setName(user.getName());
userWithAge.setAge(27);
userWithAgeList.add(userWithAge);
});
public class ListIteratorExp {
public static void main(String[] args) {
List<Person> list = new ArrayList<>();
Person p1 = new Person();
p1.setName("foo");
Person p2 = new Person();
p2.setName("bee");
list.add(p1);
list.add(p2);
list.stream().forEach(p -> {
String name = p.getName();
System.out.println(name);
});
}
}
class Person{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
output:-
vishal
thakur

Categories