I have two classes:-
public class Employee {
private String name;
private String DOB;
private String techicalSkill;
Employee(){
}
Employee(String name, String DOB, String techicalSkill){
this.name=name;
this.DOB=DOB;
this.techicalSkill=techicalSkill;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDOB() {
return DOB;
}
public void setDOB(String dOB) {
DOB = dOB;
}
public String getTechicalSkill() {
return techicalSkill;
}
public void setTechicalSkill(String techicalSkill) {
this.techicalSkill = techicalSkill;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((DOB == null) ? 0 : DOB.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((techicalSkill == null) ? 0 : techicalSkill.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (DOB == null) {
if (other.DOB != null)
return false;
} else if (!DOB.equals(other.DOB))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (techicalSkill == null) {
if (other.techicalSkill != null)
return false;
} else if (!techicalSkill.equals(other.techicalSkill))
return false;
return true;
}
#Override
public String toString() {
return "Employee [name=" + name + ", DOB=" + DOB + ", techicalSkill=" + techicalSkill + "]";
}
}
and
package learning;
public class Person {
private String address;
private int age;
private int weight;
Person(){
}
public Person(String address, int age, int weight) {
super();
this.address = address;
this.age = age;
this.weight = weight;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getWeight() {
return weight;
}
public void setWeight(int weight) {
this.weight = weight;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((address == null) ? 0 : address.hashCode());
result = prime * result + age;
result = prime * result + weight;
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (address == null) {
if (other.address != null)
return false;
} else if (!address.equals(other.address))
return false;
if (age != other.age)
return false;
if (weight != other.weight)
return false;
return true;
}
#Override
public String toString() {
return "Person [address=" + address + ", age=" + age + ", weight=" + weight + "]";
}
}
Now i have created a main class inside which the details are present:-
import java.util.ArrayList;
public class Main {
Employee e1 = new Employee();
Person p1 = new Person();
public static void main(String[] args) {
ArrayList<Employee> arraylist = new ArrayList<>();
arraylist.add(new Employee("Somduti", "31-08-1992", "Java"));
arraylist.add(new Employee("abc", "30-01-1995", "Android"));
arraylist.add(new Employee("xyz", "24-12-1988", "DotNet"));
arraylist.add(new Employee("Sanj", "01-10-1986", "IOS"));
arraylist.add(new Employee("Pink", "19-07-1991", "ETL"));
System.out.println(arraylist);
ArrayList<Person> arraylist1 = new ArrayList<>();
arraylist1.add(new Person("India", 27, 57));
arraylist1.add(new Person("US", 22, 64));
arraylist1.add(new Person("Australia", 31, 69));
arraylist1.add(new Person("France", 33, 77));
arraylist1.add(new Person("Germany", 28, 55));
System.out.println(arraylist1);
}
}
I want to add the two Objects and print the result as below:-
name=Somduti, DOB=31-08-1992, techicalSkill=Java address=India, age=27, weight=57
How do I that?
I think what you want to achieve is a relation between employees and persons. There are various ways to do that. Here are two common solutions:
Association: Add a person-field to the employee class. This looks like: "private Person person;" within the employee class.
Inheritance: An employee is a specific type of person, so you can let employee "extend" the person class. This looks like: public class Employee extends Person ...
Both ways have advantages and disadvantages. For example: Inheritance is a strong relationship, that you might want in this case. Association is a weaker type of relation, so that you could "replace" the person information of an employee (which might not be want you want).
Add the below additional field in the Employee class as follows:
public class Employee {
private String name;
private String DOB;
private String techicalSkill;
private Person person; // Additional field
Employee() {
}
/**
* #param name
* #param dOB
* #param techicalSkill
* #param person
*/
public Employee(final String name, final String dOB, final String techicalSkill, final Person person) {
super();
this.name = name;
this.DOB = dOB;
this.techicalSkill = techicalSkill;
this.person = person; //additional argument in Constructor
}
}
P.S: No changes to the Person class
Test Main:
Person person = new Person("India", 27, 57);
Employee employee = new Employee("Somduti", "31-08-1992", "Java", person);
System.out.println("name= " + employee.getName() + ", DOB= " + employee.getDOB() + ",techicalSkill= " +
employee.getTechicalSkill() + " address= " + employee.getPerson().getAddress() + ", age= " +
employee.getPerson().getAge() + " weight= " + employee.getPerson().getWeight());
Output:
name= Somduti, DOB= 31-08-1992,techicalSkill= Java address= India, age= 27 weight= 57
Related
I have json similar to this :
Groups":[
{
"LogicalOperator":"AND",
"condition":[
{
"column":"name",
"Operator":"CONTAINS",
"Value":"Shiva"
},
{
"column":"address",
"Operator":"NOT CONTAINS",
"Value":"Vijay Nagar"
},
{
"column":"city",
"Operator":"EQUAL",
"Value":"Bengaluru"
},
{
"column":"country",
"Operator":"NOT EQUAL",
"Value":"India"
}
]
}
How to find getter method based on column value.
Example: Below column is having "name", "address", "city" and "country".
If the column value is "name" then dynamically I want find getName() method, if the column value is "address" then it should be getAddress()...
Below is the pojo:
public class CustomerPojo {
private String name;
private int age;
private String address;
private String city;
private String country;
public CustomerPojo(String name, String address, String city, String country,int age) {
super();
this.name = name;
this.age=age;
this.address = address;
this.city = city;
this.country = country;
}
#Override
public int hashCode() {
return Objects.hash(address, age, city, country, name);
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
CustomerPojo other = (CustomerPojo) obj;
return Objects.equals(address, other.address) && age == other.age && Objects.equals(city, other.city)
&& Objects.equals(country, other.country) && Objects.equals(name, other.name);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
#Override
public String toString() {
return "CustomerPojo [name=" + name + ", age=" + age + ", address=" + address + ", city=" + city + ", country="
+ country + "]";
}
}
Below is the code which I have tried. But I want to do it dynamically.
private List<CustomerPojo> groupOperatorAND(JsonNode condNode, List<CustomerPojo> list) {
// String jsonNode = condNode
// System.out.println(jsonNode);
String column = condNode.findValue("column").asText();
String operator = condNode.findValue("Operator").asText();
String value = condNode.findValue("Value").asText();
switch (operator) {
case "CONTAINS":
if (column.equals("name")) {
containsList = list.stream().filter(li -> li.getName().contains(value)).collect(Collectors.toList());
} else {
containsList = list.stream().filter(li -> li.getAddress().contains(value)).collect(Collectors.toList());
}
// System.out.println(containsList);
// objList.add(containsList);
break;
case "NOT CONTAINS":
if (column.equals("name")) {
notContainsList = containsList.stream().filter(li -> !li.getName().contains(value))
.collect(Collectors.toList());
} else {
notContainsList = containsList.stream().filter(li -> !li.getAddress().contains(value))
.collect(Collectors.toList());
}
// System.out.println(notContainsList);
// objList.add(notContainsList);
break;
case "EQUAL":
if (column.equals("name")) {
equalList = notContainsList.stream().filter(li -> li.getName().equals(value))
.collect(Collectors.toList());
} else {
equalList = notContainsList.stream().filter(li -> li.getAddress().equals(value))
.collect(Collectors.toList());
}
// System.out.println(equalList);
// objList.add(equalList);
break;
case "NOT EQUAL":
if (column.equals("name")) {
notEqualList = equalList.stream().filter(li -> !li.getName().equals(value))
.collect(Collectors.toList());
} else {
notEqualList = equalList.stream().filter(li -> !li.getAddress().equals(value))
.collect(Collectors.toList());
}
//System.out.println("AND Group Result --> " + notEqualList);
// objList.add(notEqualList);
break;
default:
System.out.println("No Operator matches");
}
return notEqualList;
}
If you put this code into a static method or in a constructor so it is only executed once, it will build a map where the key is the "column" name and the value is the associated get method from your CustomerPojo class.
final Map<String, Method> getters = Arrays.asList(CustomerPojo.class.getMethods()).stream()
.filter(mth -> mth.getName().startsWith("get")).filter(mth -> !mth.getName().equals("getClass"))
.collect(Collectors.toMap(
mth -> mth.getName().substring(3, 4).toLowerCase() + mth.getName().substring(4), mth -> mth));
The code streams the array of methods from your CustomerPojo class and filters out all but the "getter" methods.
It then collects the remaining methods into a map where the key is the name of the getter after stripping off "get" and lowercasing the first character.
With this you should be able to:
Method mth = getters.get(columnName);
I have following two classes:
class Man {
private int id;
private String firstName;
private String lastName;
private int age;
private int countOfChildren;
private Address address;
}
class Address {
private Country country;
private City city;
private String street;
private long quantityOfPeople;
}
I have no idea how to group List<Man> by street and city fields of Address class. How can I do it?
Collectors class provides Collectors.groupingBy(keyProvider, downstream) you can use to group by a pair of values. To pair two values you can either use AbstractMap.SimpleEntry or you can implement your own Pair<T,K> class that represents a pair of two values (it's worth mentioning that you will have to implement hashCode() and equals(object) methods in your Pair class if you want to use it as a key in a hash map). Also two values you want to pair in a key have to implement hashCode() and equals(object) methods - it's worth using immutable classes in this case.
The whole grouping part can be done by:
final Map<Map.Entry<City, String>, List<Man>> groupedByCityAndStreet = people.stream()
.collect(Collectors.groupingBy(
man -> new AbstractMap.SimpleEntry<>(man.getAddress().getCity(), man.getAddress().getStreet()),
Collectors.toList()
));
In this example I have used AbstractMap.SimpleEntry to represent a pair of Country and street. It creates a map where for each key it groups a list of Man object based of country and street. Below you can find a full example:
import java.util.AbstractMap;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;
public class GroupByTest {
public static void main(String[] args) {
final List<Man> people = Arrays.asList(
new Man(1, "John", "Doe", 20, 0, new Address(new Country("England"), new City("London"), "Test Street 2", 10000)),
new Man(2, "Mary", "Smith", 54, 4, new Address(new Country("Germany"), new City("Berlin"), "Maine Strasse 32", 10000)),
new Man(3, "James", "Rose", 13, 0, new Address(new Country("England"), new City("London"), "Test Street 2", 10000)),
new Man(4, "Vincent", "Dog", 43, 2, new Address(new Country("Germany"), new City("Berlin"), "Volkswagen Platz 31", 10000)),
new Man(5, "Arnold", "Smoke", 72, 3, new Address(new Country("Italy"), new City("Rome"), "Pepperoni 31", 10000)),
new Man(6, "Katy", "Puppet", 33, 3, new Address(new Country("England"), new City("London"), "Test Street 3", 10000))
);
final Map<Map.Entry<City, String>, List<Man>> groupedByCityAndStreet = people.stream()
.collect(Collectors.groupingBy(
man -> new AbstractMap.SimpleEntry<>(man.getAddress().getCity(), man.getAddress().getStreet()),
Collectors.toList()
));
// Print people associated with given city and street to console
groupedByCityAndStreet.forEach((k, v) -> {
System.out.println("People associated with " + k.getKey().name + ", " + k.getValue() + ":");
v.forEach(man -> {
System.out.println(man);
});
});
}
static final class Man {
private final int id;
private final String firstName;
private final String lastName;
private final int age;
private final int countOfChildren;
private final Address address;
public Man(int id, String firstName, String lastName, int age, int countOfChildren, Address address) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.age = age;
this.countOfChildren = countOfChildren;
this.address = address;
}
public int getId() {
return id;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
public int getAge() {
return age;
}
public int getCountOfChildren() {
return countOfChildren;
}
public Address getAddress() {
return address;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Man man = (Man) o;
return id == man.id &&
age == man.age &&
countOfChildren == man.countOfChildren &&
Objects.equals(firstName, man.firstName) &&
Objects.equals(lastName, man.lastName) &&
Objects.equals(address, man.address);
}
#Override
public int hashCode() {
return Objects.hash(id, firstName, lastName, age, countOfChildren, address);
}
#Override
public String toString() {
return "Man{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", age=" + age +
", countOfChildren=" + countOfChildren +
", address=" + address +
'}';
}
}
static class Address {
private final Country country;
private final City city;
private final String street;
private final long quantityOfPeople;
public Address(Country country, City city, String street, long quantityOfPeople) {
this.country = country;
this.city = city;
this.street = street;
this.quantityOfPeople = quantityOfPeople;
}
public Country getCountry() {
return country;
}
public City getCity() {
return city;
}
public String getStreet() {
return street;
}
public long getQuantityOfPeople() {
return quantityOfPeople;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Address address = (Address) o;
return quantityOfPeople == address.quantityOfPeople &&
Objects.equals(country, address.country) &&
Objects.equals(city, address.city) &&
Objects.equals(street, address.street);
}
#Override
public int hashCode() {
return Objects.hash(country, city, street, quantityOfPeople);
}
#Override
public String toString() {
return "Address{" +
"country=" + country +
", city=" + city +
", street='" + street + '\'' +
", quantityOfPeople=" + quantityOfPeople +
'}';
}
}
static class City {
private final String name;
public City(String name) {
this.name = name;
}
public String getName() {
return name;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
City city = (City) o;
return Objects.equals(name, city.name);
}
#Override
public int hashCode() {
return Objects.hash(name);
}
#Override
public String toString() {
return "City{" +
"name='" + name + '\'' +
'}';
}
}
static class Country {
private final String name;
public Country(String name) {
this.name = name;
}
public String getName() {
return name;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Country country = (Country) o;
return Objects.equals(name, country.name);
}
#Override
public int hashCode() {
return Objects.hash(name);
}
#Override
public String toString() {
return "Country{" +
"name='" + name + '\'' +
'}';
}
}
}
When you run this example you will something like this in the console:
People associated with Rome, Pepperoni 31:
Man{id=5, firstName='Arnold', lastName='Smoke', age=72, countOfChildren=3, address=Address{country=Country{name='Italy'}, city=City{name='Rome'}, street='Pepperoni 31', quantityOfPeople=10000}}
People associated with London, Test Street 3:
Man{id=6, firstName='Katy', lastName='Puppet', age=33, countOfChildren=3, address=Address{country=Country{name='England'}, city=City{name='London'}, street='Test Street 3', quantityOfPeople=10000}}
People associated with Berlin, Volkswagen Platz 31:
Man{id=4, firstName='Vincent', lastName='Dog', age=43, countOfChildren=2, address=Address{country=Country{name='Germany'}, city=City{name='Berlin'}, street='Volkswagen Platz 31', quantityOfPeople=10000}}
People associated with Berlin, Maine Strasse 32:
Man{id=2, firstName='Mary', lastName='Smith', age=54, countOfChildren=4, address=Address{country=Country{name='Germany'}, city=City{name='Berlin'}, street='Maine Strasse 32', quantityOfPeople=10000}}
People associated with London, Test Street 2:
Man{id=1, firstName='John', lastName='Doe', age=20, countOfChildren=0, address=Address{country=Country{name='England'}, city=City{name='London'}, street='Test Street 2', quantityOfPeople=10000}}
Man{id=3, firstName='James', lastName='Rose', age=13, countOfChildren=0, address=Address{country=Country{name='England'}, city=City{name='London'}, street='Test Street 2', quantityOfPeople=10000}}
Hope it helps.
I'm currently in need of some guidance. Instead of making a huge constructor class with gets/sets. Is it possible to simplify this task?
Trying to avoid having a huge constructor with gets/sets. So I'm assuming what's a good way to avoid doing something like this. How can this sort of thing be simplified significantly?
public User(int id, String name, long skillPoints) {
this.id = id;
this.name = name;
this.skillPoints = skillPoints;
this.level = 0;
// So on so forth
}
Have you heard of Project Lombok?
By adding the annotation #Data you will get a shortcut for #ToString, #EqualsAndHashCode, #Getter on all fields, #Setter on all non-final fields, and #RequiredArgsConstructor. And there are plenty more annotations you can check out!
With Lombok
import lombok.AccessLevel;
import lombok.Setter;
import lombok.Data;
import lombok.ToString;
#Data public class DataExample {
private final String name;
#Setter(AccessLevel.PACKAGE) private int age;
private double score;
private String[] tags;
#ToString(includeFieldNames=true)
#Data(staticConstructor="of")
public static class Exercise<T> {
private final String name;
private final T value;
}
}
Vanilla Java
import java.util.Arrays;
public class DataExample {
private final String name;
private int age;
private double score;
private String[] tags;
public DataExample(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
void setAge(int age) {
this.age = age;
}
public int getAge() {
return this.age;
}
public void setScore(double score) {
this.score = score;
}
public double getScore() {
return this.score;
}
public String[] getTags() {
return this.tags;
}
public void setTags(String[] tags) {
this.tags = tags;
}
#Override public String toString() {
return "DataExample(" + this.getName() + ", " + this.getAge() + ", " + this.getScore() + ", " + Arrays.deepToString(this.getTags()) + ")";
}
protected boolean canEqual(Object other) {
return other instanceof DataExample;
}
#Override public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof DataExample)) return false;
DataExample other = (DataExample) o;
if (!other.canEqual((Object)this)) return false;
if (this.getName() == null ? other.getName() != null : !this.getName().equals(other.getName())) return false;
if (this.getAge() != other.getAge()) return false;
if (Double.compare(this.getScore(), other.getScore()) != 0) return false;
if (!Arrays.deepEquals(this.getTags(), other.getTags())) return false;
return true;
}
#Override public int hashCode() {
final int PRIME = 59;
int result = 1;
final long temp1 = Double.doubleToLongBits(this.getScore());
result = (result*PRIME) + (this.getName() == null ? 43 : this.getName().hashCode());
result = (result*PRIME) + this.getAge();
result = (result*PRIME) + (int)(temp1 ^ (temp1 >>> 32));
result = (result*PRIME) + Arrays.deepHashCode(this.getTags());
return result;
}
public static class Exercise<T> {
private final String name;
private final T value;
private Exercise(String name, T value) {
this.name = name;
this.value = value;
}
public static <T> Exercise<T> of(String name, T value) {
return new Exercise<T>(name, value);
}
public String getName() {
return this.name;
}
public T getValue() {
return this.value;
}
#Override public String toString() {
return "Exercise(name=" + this.getName() + ", value=" + this.getValue() + ")";
}
protected boolean canEqual(Object other) {
return other instanceof Exercise;
}
#Override public boolean equals(Object o) {
if (o == this) return true;
if (!(o instanceof Exercise)) return false;
Exercise<?> other = (Exercise<?>) o;
if (!other.canEqual((Object)this)) return false;
if (this.getName() == null ? other.getValue() != null : !this.getName().equals(other.getName())) return false;
if (this.getValue() == null ? other.getValue() != null : !this.getValue().equals(other.getValue())) return false;
return true;
}
#Override public int hashCode() {
final int PRIME = 59;
int result = 1;
result = (result*PRIME) + (this.getName() == null ? 43 : this.getName().hashCode());
result = (result*PRIME) + (this.getValue() == null ? 43 : this.getValue().hashCode());
return result;
}
}
}
Add Kotlin to your project, is becoming the standard, solves your problem as a charm, and as is officially supported by Google, you do not have any problem if you go in production, instead to use other libraries( that could have bugs).
Do not think that you cannot manage to transform all the project from Java to Kotlin, because Kotlin is 100 per cent compatible. One of the K features of Kotlin is just to solve your problem: avoiding to have constructor linked to instance variables and getter and setter, is a lot of boiler plate code.
you just add Kotlin to your project, will take less than 3 minutes, then you can change only the POJO classes, this is the name/acronym of the plain classes you are referring with constructors, getter and setters.
After you installed Kotlin, use Data Classes
in this way a class with 86 lines like the following will become one line. Is worthy to do it, even if you are not going to implement Kotlin to the rest of your project
public class Movie {
private String name;
private String studio;
private float rating;
public Movie(String name, String studio, float rating) {
this.name = name;
this.studio = studio;
this.rating = rating;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStudio() {
return studio;
}
public void setStudio(String studio) {
this.studio = studio;
}
public float getRating() {
return rating;
}
public void setRating(float rating) {
this.rating = rating;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + Float.floatToIntBits(rating);
result = prime * result + ((studio == null) ? 0 : studio.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Movie other = (Movie) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (Float.floatToIntBits(rating) != Float.floatToIntBits(other.rating))
return false;
if (studio == null) {
if (other.studio != null)
return false;
} else if (!studio.equals(other.studio))
return false;
return true;
}
#Override
public String toString() {
return "Movie [name=" + name + ", studio=" + studio + ", rating=" + rating + "]";
}
}
will become just
this and will get for free also toHash and toString:
data class Movie(var name: String, var studio: String, var rating: Float)
I have newly started off with Java 8 and I'm trying out some examples on Collectors. I'm following the book, Java 8 in action. I have got a doubt regarding type inference :
I have used basic model classes Student, Name to create examples. PFB the details:
package com.learning.fundamentals;
import java.util.ArrayList;
import java.util.List;
public class Student {
public enum Gender {
MALE, FEMALE;
}
private String id;
private Name name;
private Gender gender;
public Student(String id, Name name, Gender gender) {
this.id = id;
this.name = name;
this.gender = gender;
}
public String getId() {
return id;
}
public Name getName() {
return name;
}
public Gender getGender() {
return gender;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((gender == null) ? 0 : gender.hashCode());
result = prime * result + ((id == null) ? 0 : id.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (gender != other.gender)
return false;
if (id == null) {
if (other.id != null)
return false;
} else if (!id.equals(other.id))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
#Override
public String toString() {
return "Student [id=" + id + ", name=" + name + ", gender=" + gender
+ "]";
}
}
package com.learning.fundamentals;
public class Name {
private String firstName;
private String middleName;
private String lastName;
public Name(String firstName, String middleName, String lastName) {
this.firstName = firstName;
this.middleName = middleName;
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public String getMiddleName() {
return middleName;
}
public String getLastName() {
return lastName;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((firstName == null) ? 0 : firstName.hashCode());
result = prime * result
+ ((lastName == null) ? 0 : lastName.hashCode());
result = prime * result
+ ((middleName == null) ? 0 : middleName.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Name other = (Name) obj;
if (firstName == null) {
if (other.firstName != null)
return false;
} else if (!firstName.equals(other.firstName))
return false;
if (lastName == null) {
if (other.lastName != null)
return false;
} else if (!lastName.equals(other.lastName))
return false;
if (middleName == null) {
if (other.middleName != null)
return false;
} else if (!middleName.equals(other.middleName))
return false;
return true;
}
#Override
public String toString() {
return "Name [firstName=" + firstName + ", middleName=" + middleName
+ ", lastName=" + lastName + "]";
}
}
Now I have a list of Students like this
List<Student> studentList = getStudents(); //some method to create the list
Now, let's try out an grouping example. This is a multilevel grouping, first I'm grouping it using Gender and then some criteria on first name (not important). Here is the code :
Map<Student.Gender, Map<String, List<Student>>> studentsByGenderName =
studentList.stream()
.collect(Collectors.groupingBy(Student::getGender,
Collectors.groupingBy(std -> std.getName().getFirstName().substring(0, 4))));
This gives me an error at the second collector, stating "The method getName() is undefined for the type Object". Now, I was able to resolve the issue by providing the type of 'std' like this:
Map<Student.Gender, Map<String, List<Student>>> studentsByGenderName =
studentList.stream()
.collect(Collectors.groupingBy(Student::getGender,
Collectors.groupingBy((Student std) -> std.getName().getFirstName().substring(0, 4))));
My question is why can't java infer the type of the argument in lambda expression used in the second collector while it's able to do that for the first collector?
I have an array list of objects which contains eg:
Name
Address
Phone
Many other properties...
I wish to remove some objects in this list, if some of the properties has the same value as other objects in the array list. I need to loop though the whole list and see if the Name, Address and Phone already exists in this list. I can not do a simple:
for (...)
if (!newlist.contains(element)) { newlist.add(element); }
As I only need to check specific properties are the same before adding the element to a new list.
Can anyone guide me in the right direction?
How about using Set with a custom Comparator ? Have your object class implement Comparable. In the compare method you can then write your test to match the objects exactly how you need it.
Create a Key Class let us say Employee.java with below code.
package com.innovation;
public class Employee {
private String name;
private String address;
private String phone;
public Employee() {
super();
}
public Employee(String name, String address, String phone) {
super();
this.name = name;
this.address = address;
this.phone = phone;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((address == null) ? 0 : address.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((phone == null) ? 0 : phone.hashCode());
return result;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Employee other = (Employee) obj;
if (address == null) {
if (other.address != null)
return false;
} else if (!address.equals(other.address))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (phone == null) {
if (other.phone != null)
return false;
} else if (!phone.equals(other.phone))
return false;
return true;
}
#Override
public String toString() {
return "Employee [name=" + name + ", address=" + address + ", phone="
+ phone + "]";
}
}
Now create a Client class where you want to apply your logic let us assume a class containing main method say Client.java
package com.innovation;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class Client {
public static void main(String[] args) {
Set<Employee> empSet = new HashSet<Employee>(populateList());
for (Employee employee : empSet)
{
System.out.println(employee);
}
}
public static List<Employee> populateList()
{
List<Employee> lsts = new ArrayList<Employee>();
lsts.add(new Employee("rais","gurgaon","123456"));
lsts.add(new Employee("alam","Delhi","123685"));
lsts.add(new Employee("shyam","Mumbai","1257456"));
lsts.add(new Employee("ramesh","Ahmadabad","196356"));
lsts.add(new Employee("rais","gurgaon","123456"));
lsts.add(new Employee("rais","gurgaon","123456"));
lsts.add(new Employee("rais","gurgaon","123456"));
return lsts;
}
}
You will see below out put. it is clearly visible that duplicate entry present in list is removed in set. it all magic of good implementation of equals and hashcode method.
Employee [name=rais, address=gurgaon, phone=123456]
Employee [name=ramesh, address=Ahmadabad, phone=196356]
Employee [name=alam, address=Delhi, phone=123685]
Employee [name=shyam, address=Mumbai, phone=1257456]