I'm looking for the following feature describe below.
The MessageFormat of the sun api doesn't fit my need & the Spring El expression too maybe.
Assuming that we have a person Object with a name:
Person person = new Person();
person.setName("fredop");
person.setAge("25");
String messageFormat="My name is {Person.name}, i'm {Person.age} years old""
System.out.println(Translate(person,messageFormat);
In the translate method, i will pass ONLY one object.
This final line will print:
"My name is fred, i'm 25 years old"
Any idea of an actual api doing that?
Groovy, that is a Java language extension toward a ruby/python like language, allows you to easily embed variables inside strings:
String s = "Hello I'm a ${groovyname} string in which i can insert ${object.variable}"
You can do this using Spring Expression Langauge. Here is the code with example:
import org.springframework.expression.common.TemplateParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.ExpressionParser;
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
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;
}
}
class Main {
public static void main(String[] args) {
Person p = new Person("abhinav", 24);
String expression = "my name is #{name} and my age is #{age}";
System.out.println(SpelFormatter.format(expression, p));
}
}
class SpelFormatter {
private static final ExpressionParser PARSER = new SpelExpressionParser();
private static final TemplateParserContext TEMPLATE_PARSER_CONTEXT =
new TemplateParserContext();
public static String format(String expression, Object context) {
return PARSER.parseExpression(expression,
TEMPLATE_PARSER_CONTEXT).getValue(context, String.class);
}
}
Velocity is a Java-based template engine. It permits anyone to use a simple yet powerful template language to reference objects defined in Java code.
Check the User guide for syntax etc.
Related
How can we create constructor, to set different values that are from same data type?
Its impossible two create two identical constructors:
public User(int age, String name){
}
public User(int age, String surname){
}
User user1 = new User(33, Jack);
User user2 = new User(33, Sparrow);
Since both name and surname are from same data type, its impossible to know which value the user has meant to set.
We can create a constructor that has all the properties and then pass null for unset arguments.
public User(int age, String name, String surname){
}
User user1 = new User(33, Jack);
User user2 = new User(33, null, Sparrow);
There is a way to make it, using HashMap imitating the javascript object literal.
package javaapplication;
import java.awt.Color;
import java.util.HashMap;
public class JavaApplication {
public static class User {
public int age;
public String name;
public String surname;
public Color hairColor;
public User(HashMap<String, Object> arguments) {
if (arguments.containsKey("hairColor")) {
this.hairColor = (Color) arguments.get("hairColor");
}
if (arguments.containsKey("name")) {
this.name = (String) arguments.get("name");
}
if (arguments.containsKey("surname")) {
this.surname = (String) arguments.get("surname");
}
if (arguments.containsKey("age")) {
this.age = (int) arguments.get("age");
}
}
}
public static void main(String[] args) {
User jack1 = new User(new HashMap<String, Object>() {
{
put("hairColor", Color.RED);
put("name", "Jack");
put("age", 33);
}
});
System.out.println(jack1.hairColor); // java.awt.Color[r=255,g=0,b=0]
System.out.println(jack1.surname); // null
System.out.println(jack1.name); // Jack
System.out.println(jack1.age); // 33
User jack2 = new User(new HashMap<String, Object>() {
{
put("hairColor", Color.RED);
put("surname", "Sparrow");
put("age", 33);
}
});
System.out.println(jack2.hairColor); // java.awt.Color[r=255,g=0,b=0]
System.out.println(jack2.surname); // Sparrow
System.out.println(jack2.name); // null
System.out.println(jack2.age); // 33
}
}
Is there a more elegant way to do it?
The typical ways of doing this are with static creation methods or a builder object.
Static creation methods are the way to go if there are distinctive patterns of usage. For your example (where this perhaps isn't the case).
public static User ageName(int age, String name) {
...
}
public static User ageSurname(int age, String surname) {
...
}
...
In general it's a good idea to avoid any overloading. With constructors Java rather forces you into it, but sometimes you have to break free.
Builder may go something like:
public class UserBuilder { // This could be made a nested class of User
private int age = -1;
private String name;
private String surname;
private Color hairColor;
public UserBuilder age(int age) {
this.age = age;
return this;
}
// ... other properties ...
public User build() {
// Or return new User(this)
return new User(age, name, surname, hairColor);
}
}
This uses the typical Java dirty hack of returning this in a builder so you can build a train wreck.
User user1 = new UserBuilder().age(33).name("Jack").build();
You really need real examples of usage to see how it should fit in.
You are over-complicating things by using a HashMap here. Instead you could make use of the Builder Pattern for the same.
class User {
// required parameters
private int age;
// optional parameters
private String name;
private String surname;
public int getAge() {
return age;
}
public String getName() {
return name;
}
public String getSurname() {
return surname;
}
private User(UserBuilder userBuilder) {
this.age = userBuilder.age;
this.name = userBuilder.name;
this.surname = userBuilder.surname;
}
public static class UserBuilder {
// required parameters
private int age;
// optional parameters
private String name;
private String surname;
public UserBuilder setName(String name) {
this.name = name;
return this;
}
public UserBuilder setSurname(String surname) {
this.surname = surname;
return this;
}
public UserBuilder(int age) {
this.age = age;
}
public User build() {
return new User(this);
}
}
}
Now you can use it :
User user1 = new User.UserBuilder(12).setName("Jack").build();
User user2 = new User.UserBuilder(12).setSurname("Sparrow").build();
This assumes that age is a mandatory field, name and surname are optional fields for creating an object of User. You can tweak it as per your requirement accordingly.
I am using Jersy for producing Json in an application.
The code snippet which produces Json is as follows
#GET
#Produces(MediaType.APPLICATION_JSON)
#Path("sample")
public List<test> displaySampleMessage(#PathParam("id") int id)
{
System.out.println(id);
List<test> sample1 = new ArrayList<>();
test temp1 = new test();
temp1.setName("abc");
sample1.add(temp1);
return sample1;
}
Test is simple java class with the following code
package webServiceTester;
import javax.xml.bind.annotation.XmlRootElement;
#XmlRootElement
public class test
{
private String name;
private int age;
public test()
{
}
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 test(String name, int age) {
super();
this.name = name;
this.age = age;
}
}
Then when I run this web service I get the following output
I do not t want to get age = 0 here because I have not set the age property of my object.
What is its solution. I want age to be appeared if I set the value otherwise it should not appear..
Use Jakson, here you can find a
JSON example with Jersey + Jackson.
So you can use #JsonSerialize annotation to exclude null or empty fields.
#JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
or
#JsonSerialize(include=JsonSerialize.Inclusion.NON_EMPTY)
However it's not a good practice to exclude null or empty fields in restful applications because it may lead errors in client side.
While using Sqlite as DB in android, Many of us create a class like DbConstants where we save all the Table names, column names as constants.
In case of Realm DB, we prepare POJO classes which are represented as tables and fields as column names respectively.
Is there any way though which i can avoid creating another constants file here ?
Use Case :
POJO representing User table :
public class User extends RealmObject {
private String name;
private int age;
#Ignore
private int sessionId;
// Standard getters & setters generated by your IDE…
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 int getSessionId() { return sessionId; }
public void setSessionId(int sessionId) { this.sessionId = sessionId;
}
}
so while we query User table as follows :
RealmResults<User> result = realm.where(User.class)
.equalTo("name", "John")
.or()
.equalTo("name", "Peter")
.findAll();
I don`t want to use the literals like “name” here. So any other elegant solution or best practice ?
The usual practice is having a static final constant in your model class like this:
public class User extends RealmObject {
public static final String NAME = "name";
public static final String AGE = "age";
// Fields, constructors, getters, setters,
}
realm.where(Person.class).equalTo(Person.NAME, "John").findAll();
If you want an automated way of doing it you can take a look at: https://github.com/cmelchior/realmfieldnameshelper
I have built (Using Builder Pattern) an Employee object with three fields Name, Age and Gender.
public class Employee {
private String name;
private String age;
private String gender;
// Constructor
private Employee(Builder builder) {
this.name = builder.name;
this.age = builder.age;
this.gender = builder.gender;
}
// Employee Builder
public static class Builder {
private String name;
private String age;
private String gender;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder age(String age) {
this.age = age;
return this;
}
public Builder gender(String gender) {
this.gender = gender;
return this;
}
}
// Getters
public String getName() {
return name;
}
public String getAge() {
return age;
}
public String getGender() {
return gender;
}
}
Now in the Following Class I have built my Employee Object,
public class TestEmployee {
public static void main(String[] args) throws IOException {
Employee employee = new Employee.Builder().age("23").gender("Male").name("John").build();
System.out.println("Name : " + employee.getName());
System.out.println("Age : " + employee.getAge());
System.out.println("Gender : " + employee.getGender());
}
}
How can I modify the Age of the Employee "John" by breaking the already built employee object?
FYI : I don't want to have Setters in my Employee object.
You want to modify an immutable object. Do you see the problem there?
Either add setters (or any methods that mutate the state) or accept that the object is immutable.
You can of course create a new object based on the values of the old one, but it won't be the same object then.
Build another one using Copy-On-Write (reuse existing fields but change age).
Employee.Builder()
.age(employee.getAge() + 1)
.gender(employee.getGender())
.name(employee.getName())
.build();
Keep in mind, it will be another object.
ahh I was also trying to solve my problem with this approach and ironically I stumbled upon this question. I understand the challenge here, we are trying to modify an object with same builder setters but doing so we'll end up with an new object.
I figured out that there is a solution, so after approx 5yrs here's my answer LOL(to someone who's gonna end up here)
first, instead of creating duplicate properties of OuterClass in inner static Builder class. *declare an instance of outer class in Builder class. which means your build() method will return that instance.
this *declaration of instance is intended, as I am planning to create it internally or gonna ask for its memory from outside.
public class Employee {
private String name;
private String age;
private String gender;
public Static Builder builder()
{
return new Builder();
}
public Static Builder modifier(Employee employee)
{
return new Builder(employee);
}
// Employee Builder
public static class Builder {
private Employee employee;
public Builder(Employee employee)
{
this.employee = employee;
}
public Builder()
{
this.employee = new Employee();
}
public Builder name(String name) {
this.employee.name = name;
return this;
}
public Builder age(String age) {
this.employee.age = age;
return this;
}
public Builder gender(String gender) {
this.gender = gender;
return this;
}
public Employee build()
{
return this.employee;
}
}
// Getters
public String getName() {
return name;
}
public String getAge() {
return age;
}
public String getGender() {
return gender;
}
}
notice the tweak here, I introduced a modifier that takes Employee object and further allows client to modify it with Builder pattern.
So your client will use it like this...
to create new Employee
Employee employee = Employee.builder().name("abc).age(20).build();
to modify same instance
Employee.modifier(employee)
.name("xyz")
.build();
If you don't want to put setters (and make Employee mutable) you can't modify age of john... instead of this, what you can do is:
employee = new Employee.Builder()
.age("21")
.gender(employee.getGender())
.name(employee.getName())
.build();
If you don't want setters or public non-final fields, then you can add an extra constructor to the builder which will cause an initial state matching the instance, but with the builder setters available. This won't modify the original object, but create a new one based on it.
public static class Builder {
private String name;
private String age;
private String gender;
public Builder(Employee employee) {
this.name = employee.getName();
this.age = employee.getAge();
this.gender = employee.getGender();
}
public Builder name(String name) {
this.name = name;
return this;
}
public Builder age(String age) {
this.age = age;
return this;
}
public Builder gender(String gender) {
this.gender = gender;
return this;
}
public Employee build() {
return new Employee(this);
}
}
You can then use it as following.
Employee employee = new Employee.Builder().age("23").gender("Male").name("John").build();
Employee employee2 = new Employee.Builder(employee).name("Jane").build();
I have an past exam question that says:
"Create a class Element that records the name of the element as a String and has a public method, toString that returns the String name. Define a constructor for the class (that should receive a String to initialise the name)."
I gave it a go and don't where to go from here...
main class is:
public class builder {
public static void main(String[] args) {
element builderObject = new element(elementName);
}
}
and constructor is:
import java.util.*;
class element {
public int getInt(String[] args) {
Scanner scan = new Scanner(System.in);
System.out.println("Enter the first number");
String elementName = scan.nextLine();
System.out.println("%s");
}
public String toString() {
return elementName;
}
}
Don't get frustrated. Please read java tutorials first and understand the concepts. your exam question is very clear on what you need to do. Atleast for this question, you need to know what is constructor, the purpose of having toString() in a class.
May be the below can help you.
public class Element {
private String elementName;
public Element(String elementName) {
this.elementName = elementName;
}
#Override
public String toString() {
return elementName;
}
}
I can't think of a way to explain this without actually giving the answer, so....
public class Element { /// Create class Element
private final String name; // Record the 'name'
public Element(String name) { // constructor receives and sets the name
this.name = name;
}
public String toString() { // public method toString() returns the name
return name;
}
}
You are missing the constructor itself. The point of constructors is to initialize the object, usually by saving the given parameters to data members.
E.g.:
class Element {
/** A data member to save the Element's name */
private String elementName;
/** A constructor from an Element's name*/
public Element(String elementName) {
this.elementName = elementName;
}
#Override
public String toString() {
return elementName;
}
}
class Element {
private String name = "";
/**
/* Constructor
/**/
public void Element(final String name){
this.name = name;
}
#Override
public String toString(){
return name;
}
}
You don't have a constructor in there. A constructor typically looks something like this:
public class MyClass {
private String name;
private int age;
//This here is the constructor:
public MyClass(String name, int age) {
this.name = name;
this.age = age;
}
//here's a toString method just for demonstration
#Override
public String toString() {
return "Hello, my name is " + name + " and I am " + age + " years old!";
}
}
You should be able to use that as a guideline for making your own constructor.
class Element
{
private String name = "UNSET";
public String getName() { return name; }
public Element(String name) {
this.name = name;
}
public String toString() {
return getName();
}
}
You are missing a constructor you might be looking for something like this
public class Element{
private String name;
public Element(String name){ //Constructor is a method, having same name as class
this.name = name;
}
public String toString(){
return name;
}
}
A note
I take you are starting with java, In java class names usually start with capital letter, thus element should be Element. Its important that one picks up good habits early..