Instantiate objects using a helper class - java

I want to create an instance of my object, car. The problem I have is that i can create an instance of the car object such as, Car car1 = new car("Audi","A4","BF10YMR"); however I want to create car objects through a helper class. How do I call this helper class in main so that is of type car and not of type carHelper?
The car object requires a random registration number to be created and this is created in the carHelper class. The object is returned.
public class Car implements Comparable<Car>
{
public class Car
{
private String make;
private String model;
private String registration;
public Car(String make, String model, String reg)
{
this.make= make;
this.model= model;
registration = reg;
}
}
public class carHelper
{
public car genCar()
{
String reg = //some method to generate random registration.
String Make = //some method to randomly pick make from a list
String model = //some method to randomly pick model from a list
return new Car(make,model,registration);
}
}
public class Garage
{
public static void main (String args[])
{
Garage MyGarage = new Garage();
Car car1 = new Car("Audi","A4","BF10YMR") //works, but doesn't use helper
Car car2 = carHelper.genCar(); // something like this?
carHelper c = new carHelper(); // thought something like this but
System.out.println(c.genCar()); // creates object of type carHelper
// not car.
MyGarage.add(car1);
MyGarage.add(car2); // gives me carHelper cannot be converted to Car
}
}
public class GarageOp implements CarList
{
public GarageOp()
{
list = new ArrayList<Car>();
}
public boolean add(Car car)
{
if (list.contains(car) == false)
{
list.add(car);
return true;
}
}
}
Expected result is create car object using the helper class and add it to an ArrayList.

You could create this lists in the CarHelper and than, randomly, select the values and create a new Car with them. The UUID creates a random 128 bits (including hex) number and converts to a String
public class CarHelper {
private List<String> makeList = Arrays.asList("s", "t", "f", "n");
private List<String> modelList = Arrays.asList("yyt", "32g", "dc3", "aas");
public Car genCar() {
String reg = UUID.randomUUID().toString();
String make = makeList.get(new Random().nextInt(makeList.size() - 1));
String model = modelList.get(new Random().nextInt(modelList.size() - 1));
return new Car(make,model,reg);
}
}

Make the genCar() method as Static in the CarHelper class.
public car static genCar(){
// do stuff to create object
}
a non-static method can access a static variable or call a static method in Java.

Related

Can you change a immutable class?

This is a theoretical question for practice.
The question is
Create an immutable class Car.
Create some instances of car to fill an Arraylist<Car> inside a Garage class.
The MyGarage class implements these methods from Garage:
getCar(String reg) – search for the car with registration number reg.
getMake(String make) – returns a list of cars that match the given make.
totalValue() – calculates the total value of all cars in the list.
changeOwner(String reg, String ow) – change the owner of car that has registration number reg to ow.
I do not understand the changeOwner method as it is not suppose to be able to change a instances of a immutable class I thought???
This is what I have done to work around it but just seems silly
import java.util.ArrayList;
public class MyGarage implements Garage {
private ArrayList<Car> myGarage;
public MyGarage() {
myGarage = new ArrayList<Car>();
}
#Override
//Adds a Car if the registration is unique
public boolean add(Car c) {
for(Car car : myGarage) {
if(car.getRegistration().equals(c.getRegistration())) {
System.out.println("Car has the same Registration as another illegal");
return false;
}
}
myGarage.add(new Car(c.getOwner(),c.getRegistration(),c.getMake(),c.getkilometres(), c.getprice()));
return true;
}
#Override
public Car getCar(String carID) {
for(Car car : myGarage) {
if(carID.equals(car.getRegistration())) {
System.out.println("Car Found");
return car;
}
}
System.out.println("No car of that record");
return null;
}
#Override
public ArrayList<Car> getMake(String make) {
ArrayList<Car> carModel = new ArrayList<Car>();
for(Car car : myGarage) {
if (car.getMake().equals(make)) {
carModel.add(car);
}
}
System.out.println(carModel.toString());
return carModel;
}
#Override
public void totalValue() {
double amount = 0;
for(Car car : myGarage) {
amount = car.getprice() + amount;
}
System.out.println("The total amount is: " + amount);
}
#Override
public boolean changeOwner(String registration, String ow) {
for(Car car : myGarage) {
if(car.getRegistration().equals(registration)) {
myGarage.remove(car);
car = new Car(ow, "444","F-50", 4, 4000.99);
myGarage.add(car);
return true;
}
}
return false;
}
}
In object-oriented and functional programming, an immutable object
(unchangeable object) is an object whose state cannot be modified
after it is created. This is in contrast to a mutable object
(changeable object), which can be modified after it is created. In
some cases, an object is considered immutable even if some internally
used attributes change, but the object's state appears unchanging from
an external point of view. - WikiPedia
Immutable objects are thus instances whose state doesn’t change after they have been initialized. These types of classes are generally good for applications that need to implement some form of caching and where you are worried about thread-safety in a multi-threaded environment (immutable objects are inherently thread-safe).
I don't see your Car class, but assuming it'll look something like this:
public final class Car {
final String registration;
final String owner;
public Car(String registration, String owner) {
this.registration = registration;
this.owner= owner;
}
public String getRegistration() {
return registration;
}
public String getOwner() {
return owner;
}
}
... notice that there are no setter methods in this class. Hence a car can only be initialized (i.e Car myCar = new Car("abcd", "John"); and the variables in them (namely, registration and owner) can never be updated.
So your changeOwner method is essentially looping through the instances of car in your garage and when it finds a matching registration number it removes that instance of car from your garage and then adds a whole new one.
To demonstrate this, you can run the following:
public class Garage {
public static void main(String ... args) {
List<Car> myGarage = new ArrayList<>();
myGarage.add(new Car("CG404GH", "John"));
System.out.println(myGarage);
for(Car car : myGarage) {
if("CG404GH".equals(car.getRegistration())) {
myGarage.remove(car);
Car updateCar = new Car("DD404GH", "John");
myGarage.add(updateCar);
}
}
System.out.println(myGarage);
}
}
This would print out something similar to the following (the portion after the # would be different on each run):
[Car#4411d970]
[Car#6442b0a6]
The important thing to notice here is that the value after the # are different, hence they are two completely different classes (instances) of car

Reach parent class methods from arraylist of subclasses

I am trying to reach my parent class Car() variables and methods, from my ArrayList in main() of Objects Automobile(), Bus() which all inherit Car(). It gives me the opportunity to get the .Class and I know I can then compare if the class is Automobile or Bus and then do some operations, but I am actually trying to sort allInOne() ArrayList by getModel() Strings.
public class Car {
private String brand;
private String model;
public String getBrand(){
return brand;
}
public String getModel(){
return model;
}
}
public class Automobile extends Car {
int x;
Automobile(String brand, String model, int x){
super(brand, model);
this.x = x;
}
}
public class Bus extends Car {
int x;
Bus(String brand, String model, int x){
super(brand, model);
this.x = x;
}
main(){
Car first = new Automobile("brand1", "model1", 2);
Car second = new Bus("brand2", "model2", 3);
ArrayList<Object> allInOne = new ArrayList<Object>();
allInOne.add(first);
allInOne.add(second);
//here is the question part
allInOne.get(0).getBrand;
}
Instead of having Object List use ArrayList<Car>
ArrayList<Car> allInOne = new ArrayList<>();
then you can access all these methods:
allInOne.get(0).getBrand();
OR
If you want to stick to List of Object for some reason, then you can do this:
((Car) allInOne.get(0)).getBrand();
When instantiating the List, change Car as reference type instead of Object so that you might use the methods/attributes inherited from Parent Class.
ArrayList<Car> allInOne = new ArrayList<Car>(); // Java 7
ArrayList<Car> allInOne = new ArrayList<>(); // Java 8 it is not longer necessary to put reference type when instance an object.

Inherited parent class values are not reflected in JPA save entity

I have a class Vehicle and Car
Vehicle extends Car
Lets take an example
Class Vehicle {
String vehicleMade;
boolean fourWheeler;
Vehicle(String vehicleMade, boolean fourWheeler) {
this.vehicleMade=vehicleMade;
this.fourWheeler=fourWheeler;
}
// getters and setters
}
Class Car extends Vehicle {
String model;
Car(String vehicleMade, boolean fourWheeler) {
super(vehicleMade, fourWheeler);
}
// getters and setters
}
Class JavaMainClass {
private static CarInfoRepository carInfoRepo;
private static AnnotationConfigApplicationContext ctx;
public static void main(String args[]) {
carInfoRepo= ctx.getBean(CarInfoRepository.class);
//Now where I have doubt and problem
Car carInfo = new Car("Bentley", true);
carinfo.setModel("Flying Spur");
log.debug(carInfo.getVehicleMade); // I get Bentley here
carInfoRepo.save(carInfo);
}
}
Now when I get the car object from the repo, I get vehicleMade and fourWheeler attribute as null
You can see when I get that vehicleMade before saving but after saving to the repo I am getting null as the attribute.

Invoke method while creating an object

Guys please tell me what is the construction when I call method while creating an object?
for example: Person p = new Person().get.....
If you want to create an Instance of the Object with new and call the Method while creating that Object than you can call that Method in the Constructor of that Objects Class
class Person {
Person() {
method();
}
}
If you create your Object (Person) with this constructor the Method will be invoked.
If you want to call a Method after creating the Object.
Person person = new Person();
String name = person.getName();
or
String name = new Person().getName();
I guess patter Builder is what are you looking for
public class Computer {
//required parameters
private String HDD;
private String RAM;
//optional parameters
private boolean isGraphicsCardEnabled;
private boolean isBluetoothEnabled;
public String getHDD() {
return HDD;
}
public String getRAM() {
return RAM;
}
public boolean isGraphicsCardEnabled() {
return isGraphicsCardEnabled;
}
public boolean isBluetoothEnabled() {
return isBluetoothEnabled;
}
private Computer(ComputerBuilder builder) {
this.HDD=builder.HDD;
this.RAM=builder.RAM;
this.isGraphicsCardEnabled=builder.isGraphicsCardEnabled;
this.isBluetoothEnabled=builder.isBluetoothEnabled;
}
Computer comp = new Computer.ComputerBuilder(
"500 GB", "2 GB").setBluetoothEnabled(true)
.setGraphicsCardEnabled(true).build();
The closest thing that comes to mind may be singleton, but it doesn't create new objects. Person p = Person().getInstance()?

Using reflection to get a specific attribute from a extended instance

I would like to make a generic method to get a List from the parameter object.
The problem is because I have a declared object with a instance of the other class that extends the declared class.
I don't want to use the instanceof solution because the number of classes that extends LimitedValue can be big.
I thought to use reflection for a solution, but I don't know how to use that with an instance of object, in this part of the code:
Class cls = Class.forName(limitedValue.getClass().getName());
Object obj = cls.newInstance();
//This is wrong, I don't want a new instance.
Method[] methods = cls.getDeclaredMethods();
for(int x= 0; x < methods.length; x++) {
Method method = methods[x];
if ("java.util.List".equals(method.getReturnType().getName())) {
//How to get the value of this method from limitedValue instance ?
}
}
This is my full code:
public class CalculatorLimitedValue {
public static void main(String[] args) throws Exception {
StoreItem storeItem = new StoreItem(1L, "Name of StoreItem", 50L);
List listOfStoreItems = new ArrayList();
listOfStoreItems.add(storeItem);
LimitedValue limitedValue0 = new Store(listOfStoreItems);
List firstList = calculator(limitedValue0);
//do something with the list
SupermarketItem supermarketItem = new SupermarketItem(1L, "Name of SupermarketItem", 21L);
List listOfSupermarketItems = new ArrayList();
listOfSupermarketItems.add(supermarketItem);
LimitedValue limitedValue1 = new Supermarket(listOfSupermarketItems);
List secondList = calculator(limitedValue1);
//do something with the list
}
/** This is the method that I'd like to make generic to return a List */
private static List calculator(LimitedValue limitedValue) throws Exception{
Class cls = Class.forName(limitedValue.getClass().getName());
Object obj = cls.newInstance();
//This is wrong, I don't want a new instance.
Method[] methods = cls.getDeclaredMethods();
for(int x= 0; x < methods.length; x++) {
Method method = methods[x];
if ("java.util.List".equals(method.getReturnType().getName())) {
//How to get the value of this method from limitedValue instance ?
}
}
/* I don't want to use this one way, because my classes that extends LimitedValue
can be big. I would like to made a generic way to get de list of classes. */
if (limitedValue instanceof Store) {
System.out.println("This is a store");
return ((Store) limitedValue).getStoreItems();
} else if (limitedValue instanceof Supermarket) {
System.out.println("This is a supermarket");
return ((Supermarket) limitedValue).getSupermarketItems();
}
return null;
}
}
If it help, these are my other classes:
LimitedValue.class
public class LimitedValue { }
StoreItem.class
public class StoreItem {
private Long id;
private String nameOfStoreItem;
private Long valueOfStoreItem;
public StoreItem(Long id, String nameOfStoreItem, Long valueOfStoreItem){
this.id = id;
this.nameOfStoreItem = nameOfStoreItem;
this.valueOfStoreItem = valueOfStoreItem;
}
//getters and setters...
}
SupermarketItem.class
public class SupermarketItem {
private Long id;
private String nameOfSupermarketItem;
private Long valueOfSupermarketItem;
public SupermarketItem() {
}
public SupermarketItem(Long id, String nameOfSupermarketItem, Long valueOfSupermarketItem) {
this.id = id;
this.nameOfSupermarketItem = nameOfSupermarketItem;
this.valueOfSupermarketItem = valueOfSupermarketItem;
}
//getters and setters...
}
Store.class
public class Store extends LimitedValue {
private List<StoreItem> storeItems;
public Store(List<StoreItem> storeItems) {
this.storeItems = storeItems;
}
//getters and setters
}
Supermarket.class
public class Supermarket extends LimitedValue {
private List<SupermarketItem> supermarketItems;
public Supermarket(List<SupermarketItem> supermarketItems) {
this.supermarketItems = supermarketItems;
}
//getters and setters
}
You could try to use reflection here to try to achieve what you want, but it would be better to reconsider your overall design and try to use a better object oriented design that solves the problem at hand.
In particular, lets say we consider adding a method called getItems to the LimitedValue class that returns a List of items, which may be SupermarketItems or may be StoreItems. If it is structured correctly, you won't need to know the actual type because the code will be abstracted over it polymorphically.
public abstract class LimitedValue {
List<? extends Item> getItems();
}
We've now defined a new method on LimitedValue, but we also have to consider that we've introduced this new Item thing. I note that the SupermarketItem and StoreItem all share similiar attributes, name, id and value, so it seems that it might be possible to use a single class to represent them all.
public abstract class Item {
final Long id;
final String name;
final Long value;
public Item(final Long id, final Long name, final Long value) {
this.id = id;
this.name = name;
this.value = value;
}
String getName() {
return name;
}
// other getters and setters
}
public class SupermarketItem extends Item {
public SupermarketItem(final Long id, final Long name, final Long value) {
super(id, name, value);
}
}
public class StoreItem extends Item {
public StoreItem(final Long id, final Long name, final Long value) {
super(id, name, value);
}
}
Now we've completely abstracted away the need for any reflection when accessing these objects - you can simply call item.getValue() as you will know that every item in the list is of type Item.
Of course, you'll also need to refactor the Store and SuperMarket classes, for example:
public class Supermarket extends LimitedValue {
private List<SupermarketItem> supermarketItems;
public Supermarket(List<SupermarketItem> supermarketItems) {
this.supermarketItems = supermarketItems;
}
public List<? extends Item> getItems() {
return supermarketItems;
}
}
and because you are only returning a List<Item> you always know what is in it, and you can change your main code to work with this.
This is a much cleaner long term solution.
To get the List value, use Method#invoke:
List list = method.invoke(limitedValue);
You don't need Object obj = cls.newInstance(); - you're not using it at all in the method.
In any case, you're making it very difficult for yourself. You could also define an interface
public interface HasList<E> {
List<E> getList();
}
and have all classes implement this.

Categories

Resources