I have 2 lists:
List<User1> users;
List<User2> users_;
Data Models User1 and User2 are completely similar except for their class names. They have been named differently only because i use them in a heterogeneous adapter and use instance of to ascertain view type
I would like to equate users to users_ at some point. How can i achieve this as simple type casting doesn't seem to work here:
EDIT:
User1 (which is the Same as User2 except for class name)
public class User1 {
private String first_name, last_name;
private int age;
public int getAge() {
return age;
}
public String getFirst_name() {
return first_name;
}
public String getLast_name() {
return last_name;
}
public void setAge(int age) {
this.age = age;
}
public void setFirst_name(String first_name) {
this.first_name = first_name;
}
public void setLast_name(String last_name) {
this.last_name = last_name;
}
}
The error arises in the following:
void exchangeData(){
users = users_;
}
The error being:
Required: List <User1>, Found: List <User2>
Even
void exchange(){
users.clear();
users.addAll(users_);
}
raises the same error
Make an interface User (with the getters and setters you want) and make both User1 and User2 implement this interface.
Now (if I understand the question correctly), instead of List<User1> and List <User2> just use List<User> to compare them.
Also why are you mixing camel and snake case? Surely you want getFirstName() instead of getFirst_name()? Makes my eyes bleed.
I am trying to learn how to implement a CRUD ReST API. I created a simple application using JAX-RS and am testing my HTTP methods using Postman. My question is, how do I define optional fields for a model for POST method?
ex. Person contains firstName, lastName as required fields, and age, gender as optional fields.
#XmlRootElement
public class Person {
private long id;
private String firstName;
private String lastName;
public Person() {}
public Person(long id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
//getter and setters omitted
Above is a sub-resource to another resource, and below addPerson service method is used to POST to a HashMap.
public Person addPerson(long userId, Person person) {
Map<Long, Person> persons = users.get(userId).getPersons();
person.setId(persons.size() + 1);
persons.put(person.getId(), person);
return person;
}
I thought of constructing a model whose constructor has multiple different combination of parameters to instantiate a model class, but that doesn't seem very efficient. Can somebody advise?
FURTHER EDIT: This needs to be done while processing JSON. Given two JSON formatted request:
{
"firstName": "Jay",
"lastName": "Kay",
"age": "13"
}
and
{
"firstName": "Jay",
"lastName": "Kay"
}
both should be processable since age(as well as gender) is an "optional attributes" so it may be either omitted, or have a value. I'm coming across JSON parsers and trying to read through them since that may be an answer to processing such requests.
Add gender and age to your Person class
#XmlRootElement
public class Person {
private long id;
private String firstName;
private String lastName;
private int age;
private String gender;
public Person() {}
public Person(long id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
}
While making request from Postman, include the age and gender as keys in x-www-form-urlencoded.
By default, the value of integer is 0 and value for String is empty string.
In your method to handle the request, check the values for gender and age.
If the values are provided in the request, then use the setters of Person class to set the values accordingly.
Suppose the following is your method to handle the request :
#POST
#Path("/AddPerson")
#Produces(MediaType.TEXT_PLAIN)
public String addPerson(#FormParam("id") long id,
#FormParam("firstName") String firstName,
#FormParam("lastName") String lastName,
#FormParam("age") int age,
#FormParam("gender") String gender) {
Person person = new Person(id,firstName,lastName);
if(age != 0) {
person.setAge(age);
}
if(!gender.equals("")) {
person.setGender(gender)
}
// Assuming that PersonService class has the addPerson method
PersonService.addPerson(1,person)
return "Person with id "+ id + " added";
}
I'm developing a service using apache thrift. I have a service named getUser which returns User object. I couldn't find any way to define user-defined data type as a return type for my service defined in .thrift file.
user.thrift file looks like:
service UserService
{
User getUser(1:i32 userId),
}
When I am compiling the user.thrift to generate java source code, I am getting "Type "User" has not been defined" error. Can anyone please help me, how to represent this user-defined java object as a data type in thrift.
The getUser method code in service implementation class:
#Override
public User getUser(int user id) throws TException {
// here is the code that fetch the user object from database
return user;
}
This is my User class, whose object is being returned by service getUser:
public class User {
private int userId;
private String name;
private String city;
private String country;
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
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;
}
}
The relevant IDL could look like this:
struct User {
1 : i32 userId
2 : string name
3 : string city
4 : string country
}
So that's pretty straightforward. With that, you have two options:
use the Thrift-generated class as the data object, replacing your existing class
write some code that converts the data back and forth.
Both options have their pros and cons. With the first approach, you will lose the getter-only for the Id, because the field must be read/writable. But you don't have to convert any data.
The second approach leaves you with the getter/setter structure you have right now, with some minor modifications (the factory pattern could be worth a look). You pay that with the burden of additional data conversion from Thrift into your class and back.
It depends on the exact requirements, which option is the better one for your case.
I have some old code which is working fine but now i want to use #JsonCreator in domain objects and i am able to re-factor all stuff but i am now stucked in one issue. In one scenario i have Json Structure like:
[{
"name" : "John",
"emailAddress" :"stucked#gmail.com"
}]
But in java backend i have structure like:
class Employee {
public final String name;
public final EmailAddress emailAddress;
Employee(final String name, final EmailAddress emailAddress) {
this.name = name;
this.emailAddress = emailAddress;
}
Employee() {
this(null, null)
}
}
class EmailAddress {
public final String address;
EmailAddress(final String address) {
this.address = address;
}
EmailAddress() {
this(null);
}
}
So I am trying like :
class Employee {
public final String name;
public final EmailAddress emailAddress;
#JsonCreator
Employee(#JsonProperty("name")final String name,
#JsonProperty("emailAddress")final EmailAddress emailAddress) {
this.name = name;
this.emailAddress = emailAddress;
}
}
class EmailAddress {
public final String address;
#JsonCreator
EmailAddress(#JsonProperty("address")final String address) {
this.address = address;
}
}
Now the problem is in using #JsonProperty with "emailAddress" field in Employee domain object and then #JsonProperty inside EmailAddress Object with "address" because in Json i dont have any "address" property and due to which JsonParsing error is coming.
Well problem can be easily solved if i declare emailAddress as String instead of EmailAddress and remove EmailAddress object but address field of EmailAddress object is used at many other places, modification of which require lot of effort and there are lots of such cases. Is there any other solution??
So what exactly is your problem here? If the goal is to allow both of these:
"stucked#gmail.com"
{ "address" : "stucked#gmail.com" }
it should already work: Jackson figures out that single-String constructor may be used if JSON String is found; and setters/fields if a JSON Object is found. You just need to ensure names match ("address" vs "emailAddress").
I have an abstract class Customer. It's a very simple class, only setting 5 string variables as well as 5 static int variables. Better to show what I mean by this:
As a disclaimer I made the code as simple as possible, I have more logic involved in my abstract class that doesn't pertain to the question.
Abstract Class
public abstract class Customer {
private String Name, Address, Phone, Email, Company;
public static final int NAME = 0, ADDRESS = 1, PHONE = 2, EMAIL = 3, COMPANY = 4;
public Customer(String Name, String Address, String Phone, String Email, String Company) {
setValues(Name, Address, Phone, Email, Company);
}
private void setValues(String Name, String Address, String Phone, String Email, String Company) {
setName(Name);
setAddress(Address);
setPhone(Phone);
setEmail(Email);
setCompany(Company);
}
//declare public getters and setters methods below
}
My question is as follows:
I have a class that extends this abstract class called Customer (different package). If I set up the constructor in this class as such:
Object Class
public class Customer extends Main.Customer {
private String Name, Address, Phone, Email, Company;
public Customer(String Name, String Address, String Phone, String Email, String Company) {
super(Name, Address, Phone, Email, Company);
}
}
Does this set my String variables as to whatever I pass through the constructor? As in when I instantiate this class as an object, how would I be able to 'get' a variable from it?
For example: (Assume String1 -String5 are strings of some sort)
public class Random {
private Customer customer = new Customer(String1, String2, String3, String4, String5);
}
How would I then call the object later on in the class to return a string (of any single variable). As in if my abstract class wasn't abstract but the main class I was using to instantiate as an object, I'd get the variable like so: String name = customer.getName();
TL;DR:
Just unsure how to get variables from an object extending an abstract class.
Drop the variables from your subclass so they don't shadow the variables with the same name in the parent class.
//sub class
public class Customer extends Main.Customer {
//DROP THESE private String Name, Address, Phone, Email, Company;
public Customer(String Name, String Address, String Phone, String Email, String Company) {
super(Name, Address, Phone, Email, Company);
}
}
And add getters to your parent class:
//parent class
public abstract class Customer {
private String Name, Address, Phone, Email, Company;
public static final int NAME = 0, ADDRESS = 1, PHONE = 2, EMAIL = 3, COMPANY = 4;
public Customer(String Name, String Address, String Phone, String Email, String Company) {
setValues(Name, Address, Phone, Email, Company);
}
private void setValues(String Name, String Address, String Phone, String Email, String Company) {
setName(Name);
setAddress(Address);
setPhone(Phone);
setEmail(Email);
setCompany(Company);
}
public String getName() {
return Name;
}
public String getAddress() {
return Address;
}
//etc....
}
Also, I really recommend using different names for your parent and subclass to avoid confusion.
Some considerations before start:
In java by code-convention variables starts with lower-case. It will help code readability for people including you.
Don't have two classes with the same name, is very confusing. You can call it for example ACustomer or AbstractCustomer and the other one Customer or SomethingCustomer
It isn't Object class it's Concrete Class a class that you can have instances of it.
As Customer inherits ACustomer you don't have to define again the ACustomer fields, Customer already has them. If you do you are hiding those from parent.
public class Customer extends ACustomer {
public Customer(String name, String address, String phone, String email, String company) {
super(name, address, phone, email, company);
}
}
You are calling an overrideable method inside the constructor take care about that, cause if setXXX is override then perhaps you could have a NullPointerException.
For your question in how to get member you can define getters.
public abstract class ACostumer{
private String name;
public String getName() {
return name;
}
}
Then in client code:
ACustomer customer = new Customer(...);
customer.getName();
Your subclass is overshadowing the private properties of the abstract class.
public abstract class Customer {
private String Name, Address, Phone, Email, Company;
public class Customer extends Main.Customer {
private String Name, Address, Phone, Email, Company;
so any get methods in your abstract class of the form
public String getName() {
return Name;
}
would return the never initialized variable name in the subclass. Whereas, when you call super(...), the set functions there would set the variables of the abstract class.
So you are setting one set of variables, but reading another set of variables that were never initialized.