Calling Secondary constructor to Secondary Constructor in Kotlin - object

I am new to OOP in Kotlin. I have a strong base in Java. But I am facing this issue which is unresolved.
This is the java code:-
public class Parent {
String name;
int age;
boolean isAlive;
Parent(String name, int age) {
this.name = name;
this.age = age;
}
Parent(boolean isAlive) {
this.isAlive = isAlive;
}
}
final class Child extends Parent {
Child(String name, int age) {
super(name, age);
}
Child(boolean isAlive) {
super(isAlive);
}
}
I don't know how to write this code in Kotlin. How do you call a parent secondary constructor from the child secondary constructor?

Isn't it just
class Child: Parent {
constructor(name: String, age: Int): super(name, age)
constructor(isAlive: Boolean): super(isAlive)
}
?

Related

Array list object help (static error)

import java.util.Scanner;
import java.util.ArrayList;
public class fester
{
public static void main(String args[] )
{
ArrayList<BankAccount> ba = new ArrayList<BankAccount>();
ba.add(new BankAccount("hi", 4));
}
class BankAccount
{
private String name;
private double amount;
public BankAccount(String name, Double amount)
{
this.name = name;
this.amount = amount;
}
public String getName()
{
return this.name;
}
public double getAmount()
{
return this.amount;
}
}
}
I dont get problem. I tried to almost copy this
http://www.java2s.com/Code/Java/Collections-Data-Structure/Storeuserdefinedobjectsinarraylist.htm
and it works. I'm very lost, and I cant see the fundamental differences.
You constructed class BankAccount as nested inner class (which means that you need an object of the outer class in order to instantiate it).
Move it outside of fester and replace 4 with 4.0 it'll work:
class fester {
public static void main(String args[]) {
ArrayList<BankAccount> ba = new ArrayList<BankAccount>();
ba.add(new BankAccount("hi", 4.0));
}
}
class BankAccount {
private String name;
private double amount;
public BankAccount(String name, Double amount) {
this.name = name;
this.amount = amount;
}
public String getName() {
return this.name;
}
public double getAmount() {
return this.amount;
}
}
Comment: You should follow Java naming convention and rename fester to Fester (with a capital letter).

groovy not recognizing java getters/setters through field syntax

I have the following inheritance hierarchy defined in java.
public class BaseModel extends HashMap<String, Object> {
public String getString(String key) {
return (String)this.getOrDefault(key, "EMPTY");
}
}
public class Entity extends BaseModel {
private String id;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
Now in a groovy script I try to do the following:
Entity entity = new Entity();
entity.id = "101";
entity.name = "Apple"
and "id" and "name" are not recognized. The funny thing is they are recognized if I do one of the following:
not inherit Entity from BaseModel
Rather than inherit BaseModel from HashMap, make HashMap a data member of BaseModel
inherit Entity directly from HashMap
At first I thought that groovy is not recognizing the "id" and "name" syntax because of extending HashMap, but #3 above proves that incorrect. I am stumped as to why this is not being recognized at this point. Can someone help me out? It should be easy enough to copy paste this and try it out yourself.
The problem seems to be the setters and getters inside the Entity Class, everything in groovy is public and it creates all the getters and setters methods.
I tested the next code in the groovy console and it worked.
public class BaseModel extends HashMap<String, Object> {
public String getString(String key) {
return (String)this.getOrDefault(key, "EMPTY");
}
}
public class Entity extends BaseModel {
private String id;
private String name;
}
Entity entity = new Entity();
entity.id = "101";
entity.name = "Apple"
println entity.id
It prints 101 in the groovyConsole output screen.
When Entity is extending from BaseModel or directly a HashMap, Entity becomes a Map. So, when we say entity.id, Groovy is trying to find an entry in the map whose key is 'id'. As there is no such entry, it prints out null.
public class Entity extends HashMap<String, String> {
private String id;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
Entity entity = new Entity();
entity.id = "101";
entity.name = "Apple"
println entity.id //prints null
But when Entity is not extending from BaseModel anymore, entity.id will be interpreted just as a member of Entity.
public class Entity {
private String id;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
}
Entity entity = new Entity();
entity.id = "101";
entity.name = "Apple"
println entity.id //prints 101

Spring-data-cassandra's CassandraTemplate returns String, not a specified Object, when run queryForObject function.

I've been going through the Spring Data Cassandra documentation (http://docs.spring.io/spring-data/cassandra/docs/1.0.1.RELEASE/reference/html/cassandra.core.html)
Basically, with proper annotation, I hoped the CassandraTemplate maps a row to a POJO object, but it didn't work as I expected.
For the call,
cassandraOps.queryForObject(s, Person.class)
I received an error as following:
Exception in thread "main" java.lang.ClassCastException: java.lang.String cannot be cast to Person
Anything that I'm missing? Following is the same copy and paste from the doc above.
Person Class looks like:
#Table
public class Person {
#PrimaryKey
private String id;
private String name;
private int age;
public Person(String id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
#Override
public String toString() {
return "Person [id=" + id + ", name=" + name + ", age=" + age + "]";
}
}
and the application class looks like...:
public class CassandraApp {
private static final Logger LOG = LoggerFactory.getLogger(CassandraApp.class);
private static Cluster cluster;
private static Session session;
public static void main(String[] args) {
try {
cluster = Cluster.builder().addContactPoints(InetAddress.getLocalHost()).build();
session = cluster.connect("mykeyspace");
CassandraOperations cassandraOps = new CassandraTemplate(session);
cassandraOps.insert(new Person("1234567890", "David", 40));
Select s = QueryBuilder.select().from("person");
s.where(QueryBuilder.eq("id", "1234567890"));
LOG.info(cassandraOps.queryForObject(s, Person.class).getId());
cassandraOps.truncate("person");
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}
CassandraTemplate's queryForObject(String,Class) is not meant for arbitrary object mapping. It is modeled after JdbcTemplate's queryForObject(String,Class) method. It's intended to take types that the Cassandra driver can convert directly.
To convert arbitrary application-defined classes, use queryForObject(String,RowMapper<T>) or one of its overloads. CqlTemplate doesn't know how to map arbitrary classes; you have to supply the RowMapper<T> implementation for your class T.
you can do it like this way:-
String myQuery = "select * from person where id=1234567890";
Person personObj = cassandraOperations.selectOne(myQuery, Person.class);
<<
For all
List<Person> personListObj = cassandraOperations.select(myQuery, Person.class); >>
this work for me using cassandraTemplete object perfectly... didn't try for cassandraOperation.
also you might need #Column(value = "your_columnName_in_DB") if your pojo class's variable name is different
like
#Column(value = "name")
private String userName;
#Column(value = "age")
private int userAge;
revert here if its work?
Also can you help me pass dynamic value to that myQuery string.. using object[] same like prepareStatment in SQL
thanks.

HashMap<String, Student> searching for instance in Student class

I am working with two helper classes (Student, Helper), as well as a main class.
In the Student class, I have the following constructor:
Student(String iName, String iMajor, int iNumber) {
name = iName;
major = iMajor;
number = iNumber;
}
In the Helper class, I declare a HashMap as follows:
HashMap<String, Student> students = new HashMap<String, Student>();
Now, I have written a few method for adding (put) new students into the HashMap construction, as well as a method for retrieving information about a student based on the name.
//Adding new students
Student s1 = new Student("Alex", "Biology", 19);
Student s2 = new Student("Brian", "Chemistry", 20);
Student s3 = new Student("Tom", "Biology", 20);
//etc...
//Get student from name (key)
public Student getFromKey(String key) {
return students.get(key);
}
I am now looking to write a method that finds all students based on either major or number. For instance, the call:
helper.getStudents("Biology");
Should return all the students studying Biology. I imagine the method looking something like:
public Student getStudents(String searchItem) {
for(Students st : students.values()) {
if(searchItem.equals(??)) {
return st;
//Something like this.
However, I can't seem to figure out how to access these values. All the classes have appropriate getter and setter methods, and the program works fine. Any help is highly appreciated!
Assuming this Map exists:
HashMap<String, Student> students = new HashMap<String, Student>();
The following would work:
public Student getStudents(String searchItem) {
for(Map.Entry<String,Student> entry : students.entrySet()) {
Student student = entry.getValue();
//perform conditional logic here
}
Here is a more complete example in case you need it:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class Student {
private String name;
private String major;
private int number;
public Student(String name, String major, int number) {
super();
this.name = name;
this.major = major;
this.number = number;
}
public static void main(String[] args) {
List<String> names = Arrays.asList("Joe", "Jack", "John","James");
List<String> majors = Arrays.asList("English","Math","Geography");
Map<String,Student> students = new HashMap<String,Student>();
for(int i = 0; i < 100; i++){
Collections.shuffle(names);
Collections.shuffle(majors);
students.put(names.get(0) + String.valueOf(i), new Student(names.get(0), majors.get(0), i));
}
List<Student> mathMajors = getStudents(students, "Math");
for(Student student:mathMajors){
System.out.println(student.name);
System.out.println(student.major);
}
}
public static List<Student> getStudents(Map<String,Student> students, String searchToken){
List<Student> results = new ArrayList<Student>();
for(Entry<String,Student> entry:students.entrySet()){
if(entry.getValue().getMajor().equalsIgnoreCase(searchToken)){
results.add(entry.getValue());
}
}
return results;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getMajor() {
return this.major;
}
public void setMajor(String major) {
this.major = major;
}
public int getNumber() {
return this.number;
}
public void setNumber(int number) {
this.number = number;
}
}
On Github

Do not include few parent class elements when XML constructed from child

Is it possible to not have few fields from parent class when XML is constructed out of the child class?
But the elements should be present when XML is constructed from parent class?
Example
Parent class
#XmlRootElement(name = "location")
#XmlType(propOrder = { "id", "name" })
#JsonPropertyOrder({ "id", "name" })
public class Parent {
private Integer id;
private String name;
#XmlElement(name = "id", nillable = true)
#JsonProperty("id")
public Integer getId() {
return super.getId();
}
#JsonProperty("id")
public void setId(Integer id) {
super.setId(id);
}
#XmlElement(name = "name", nillable = true)
#JsonProperty("name")
public String getName() {
return name;
}
#JsonProperty("name")
public void setName(String name) {
this.name = name;
}
}
Child class
#XmlRootElement(name = "location")
#XmlType(propOrder = { "id" })
#JsonPropertyOrder({ "id" })
public class Child extends Parent {
#XmlElement(name = "id", nillable = true)
#JsonProperty("id")
public Integer getId() {
return super.getId();
}
#JsonProperty("id")
public void setId(Integer id) {
super.setId(id);
}
}
I do not want the name field when XML is constructed from child class. However it should be present when XML is constructed from parent class.
Try to override the getter and setter for name in the subclass and annotate them with #JsonIgnore and/or #XmlTransient.
EDIT
Indeed, #XmlTransient does not work with polymorphism as I expected (and as #JsonIgnore do). What you can try is:
-- move all content of Parent class to an abstract Base class
-- mark Base as #XmlTransient
-- make Parent extend Base and add no content to it
-- make Child extend Base
Here is some synthetic example I worked on. It can easily be translated to your particular classes.
Class Base
#XmlRootElement(name = "location")
#XmlSeeAlso(value = {Parent.class, Child.class})
#XmlTransient
public abstract class Base {
private String a;
private String b;
#XmlElement(name = "a")
public String getA() {
return a;
}
public void setA(String a) {
this.a = a;
}
#XmlElement(name = "b", nillable = true)
public String getB() {
return b;
}
public void setB(String b) {
this.b = b;
}
}
Class Parent
#XmlRootElement(name = "location")
#XmlType
public class Parent extends Base {
}
Class Child
#XmlRootElement(name = "location")
#XmlType
public class Child extends Base {
private String c;
#XmlElement(name = "c")
public String getC() {
return c;
}
public void setC(String c) {
this.c = c;
}
#Override
#XmlTransient
public String getB(){
return super.getB();
}
#Override
public void setB(String b) {
super.setB(b);
}
}
Obviously, if the class hierarchy grows larger, it may be harder to maintain such a workaround. In those cases, you may think about choosing composition rather than inheritance.

Resources