Does BeanUtils.copyProperties make a deep clone? - java

To test this, I quickly whipped up the following :
public class Test {
public static void main(String[] args) {
try {
Employee e = new Employee();
e.setName("A");
Employee y = new Employee();
// y=e;
BeanUtils.copyProperties(y, e);
e.setName("B");
System.out.println(y.getName());
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Employee{
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
This should have printed A instead it prints null. What went wrong here ?
How can I really copy properties from one object to another (and not have them point to the same values), and does BeanUtils.copyProperties create a deep copy in the first place ?

You need to make your Employee class public. This code worked for me (and compiles):
package com.sandbox;
import org.apache.commons.beanutils.BeanUtils;
public class Sandbox {
public static void main(String[] args) {
try {
Employee e = new Employee();
e.setName("A");
Employee y = new Employee();
// y=e;
BeanUtils.copyProperties(y, e);
e.setName("B");
System.out.println(y.getName());
} catch (Exception e) {
e.printStackTrace();
}
}
public static class Employee {
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
}
When I removed the public from Employee, it printed "null".

Related

I need to get the max from a Employee class from a Farm class

I need to find and display the the employee who has the maximum salary from the Farm.
this is what I got so far
public class Employee implements Comparable<Employee> {
private String name;
private Integer salary;
public Employee (String name , Integer salary) {
this.name = name;
this.salary = salary;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setSalary(Integer salary) {
this.salary = salary;
}
public Integer getSalary() {
return salary;
}
public String toString() {
return name + " " + salary;
}
public int compareTo(Employee emp) {
return this.salary.compareTo(emp.getSalary());
}
}
Employee class
public class Farm {
private String name;
private Integer surface;
List<Employee> emp = new ArrayList<Employee>();
public Farm(String name , Integer surface) {
this.name = name;
this.surface = surface;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setSurface(Integer surface) {
this.surface = surface;
}
public int getSurface () {
return surface;
}
public String toString() {
return name + " " + surface;
}
public void makeList(String ename , Integer esalary) {
this.emp.add(new Employee(ename,esalary));
}
public void getList() {
for(Employee el : emp)
System.out.println(el);
}
}
And the last one is the main. The thing is that I don't know how can I have more farms and get the max from every single one of them. Can you guys help me?
And this is my mainapp
public class Mainapp {
public static void main(String args[])
{
List <Farm> FarmList = new ArrayList<Farm>();
FarmList.add(new Farm("unirea pizdii", 890030));
FarmList.add(new Farm("pseudo autsm",78594));
FarmList.add(new Farm("haha hihi",854856099));
Farm farm1 = new Farm("Tiguana" , 700);
farm1.makeList("Mihai", 30000);
farm1.makeList("Vladimir", 4000);
farm1.makeList("Tusnic", 3000);
farm1.getList();
Employee emp1 = new Employee(" mihai", 3000);
System.out.println(emp1);
}
}
To get employee with max salary for each farm you can use stream api:
import static java.util.stream.Collectors.*;
Map<Farm, Optional<Employee>> collect =
farmList.stream().collect(groupingBy(Function.identity(),
flatMapping(farm -> farm.getEmployes().stream(),
maxBy(Employee::compareTo))));
Result map has Farm as a key and Employee with max salary as a value
Note: flatMapping method is from java9
There are multiple ways to sort a List in Java, one of them being Collections.sort(List), but in this case it looks like you are trying to retrieve the maximum value from the list, so there's no need to add the extra overhead.
EDIT: JB Nizet suggested using Collections.max(List):
public Employee getMostPaidEmployee() {
return Collections.max(emp);
}
One way to get the most paid employee from the list would be to loop through them and compare each one to the previously "saved" most paid employee:
// Farm.java
public Employee getMostPaidEmployee() {
Employee mostPaid = null;
// Initialize maximum to the lowest possible value.
// If salaries can only be positive you could also initialize this to `0`.
int maximumSalary = Integer.MIN_VALUE;
for (Employee employee : emp) {
if (employee.getSalary() > maximumSalary) {
// Reset the most paid fields
mostPaid = employee;
maximumSalary = employee.getSalary();
}
}
return mostPaid;
}
You can declare this method on the Farm class, so you will be able to call it even if you have multiple instances of Farm:
List<Farm> farms = new ArrayList<>();
// TODO Add farms
// Get the most paid employee in first farm
Employee mostPaid = farms.get(0).getMostPaidEmployee();
In terms of performance, this method is linear, i.e. O(n).

Convert composite java object to CSV with Jackson

With Jackson, I need to convert an instance of my class Test in CSV but I'm getting problems with a class that contains one list (Inner)
Ex:
public class Test {
String testName;
#JsonUnwrapped
Simple simple;
#JsonUnwrapped
Inner inner;
public Test(String testName, Simple simple, Inner inner) {
this.testName = testName;
this.simple = simple;
this.inner = inner;
}
public String getTestName() {
return testName;
}
public void setTestName(String testName) {
this.testName = testName;
}
public Simple getSimple() {
return simple;
}
public void setSimple(Simple simple) {
this.simple = simple;
}
public Inner getInner() {
return inner;
}
public void setInner(Inner inner) {
this.inner = inner;
}
}
class Inner {
#JsonUnwrapped
List<Person> persons;
public Inner(List<Person> persons) {
this.persons = persons;
}
public List<Person> getPersons() {
return persons;
}
public void setPersons(List<Person> persons) {
this.persons = persons;
}
}
class Person {
String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Simple {
String simpleName;
public Simple(String simpleName) {
this.simpleName = simpleName;
}
public String getSimpleName() {
return simpleName;
}
public void setSimpleName(String simpleName) {
this.simpleName = simpleName;
}
}
class Main {
public static void main(String[] args) {
Simple simple = new Simple("simple");
Person person = new Person("jesus");
Inner inner = new Inner(Arrays.asList(person));
Test test = new Test("test", simple, inner);
CsvMapper mapper = new CsvMapper();
CsvSchema schema = mapper.schemaFor(Test.class);
try {
String csv = mapper.writer(schema).writeValueAsString(test);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
}
}
For objects properties, I used the annotation #JsonUnwrapped as recommended on this link ,
but I get one exception when jackson try to convert the list Inner.persons:
How can I fix that ?

Set Data in Bean Class

I am stuck in an operation. I have 2 POJO Bean Classes
class A{
private String name;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
..................................................................
class B {
private String company;
private Object object;
public String getCompany() {
return company;
}
public void setCompany(String company) {
this.company = company;
}
public String getObject() {
return object;
}
public void setObject(String object) {
this.object = object;
}
}
..........................................................
class SampleTest {
public static void main(String[] args) {
A a = new A();
a.setName("Some Data");
B b = new B();
b.setCompany("Stack Overflow");
b.setObject(a);
//...... Next Lines.....
}
}
Is there any way to set data in B pojo class by reading any Property file?
Example Property file:
#Property File<br>
B.company = Stack Overflow<br>
B.object.name = Some Data
Please help.
Thank you
One way can be :
Properties prop = new Properties();
try
{
// load a properties file
prop.load(new FileReader("config.properties"));
// get the property value
B b = new B();
b.setCompany(prop.getProperty("B.company"));
}
catch (IOException ex)
{
ex.printStackTrace();
}

apache commons beanutils, how to set property value?

In the java, commons beanutils, try to set property 'address' and 'creditCardList' to object, but it gave me error :
java.lang.NoSuchMethodException: Property 'address' has no setter method in class 'class com.dao.Student'
but I have this method there. The code is here:
public class Main {
public static void main(String[] args) {
Object student = new Student("John");
Object address = new Address("NJ");
try {
PropertyUtils.setProperty(student, "address", address);
//----------
List list = new ArrayList();
Object creditCard = new CreditCard();
list.add(creditCard);
PropertyUtils.setProperty(student, "creditCardList", list);
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Student {
private String name;
private Address address;
private List<CreditCard> creditCardList;
public Student(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public List<CreditCard> getCreditCardList() {
return creditCardList;
}
public void setCreditCardList(List<CreditCard> creditCardList) {
this.creditCardList = creditCardList;
}
}
class Address {
private String name;
public Address(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class CreditCard{
private String cardName;
public String getCardName() {
return cardName;
}
public void setCardName(String cardName) {
this.cardName = cardName;
}
}
Your class Student should be a public class , try making it public and rerun your code.
I moved Student to a own file and made it public, that worked fine :)

OGNL setValue target is null

public class Customer {
private User user;
private String name;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class User {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public static void main(String[] args) {
try {
Customer customer = new Customer();
Object tree = Ognl.parseExpression("user.name");
Ognl.setValue(tree, customer, "hello");
} catch (OgnlException e) {
e.printStackTrace();
}
}
ognl.OgnlException: target is null for setProperty(null, "name", hello)
how to let ognl to create user auto.
Try this
public static void main(String[] args) {
try {
Customer customer = new Customer();
User user = new User();
customer.setUser(user);
Object tree = Ognl.parseExpression("user.name");
Ognl.setValue(tree, customer, "hello");
} catch (OgnlException e) {
e.printStackTrace();
}
}
The problem with your sample code is that your instance "customer" has a null user. So OGNL is essentially calling customer.getUser().setName("hello"), where "customer.getUser()" returns null.

Categories

Resources