I am not sure if I am doing some silly mistake, What I am trying to achieve is I have JSON list and I want to convert them into multiple objects depending on variable argument passed to function.
Unit u1= new Unit();
User us = new User();
//calling funtion
StaticUtil.MagicJsonMapper(list, u1,us);
System.out.println(u1.getUnitName()); //place -1 unitName is null after function call
Inside static class I have create a function
#SuppressWarnings("rawtypes")
public static void MagicJsonMapper(List list,Object... objects){
if(list.size()!= objects.length){
//TODO
System.out.println("parame`ter mismatch");
return;
}
int i=0;
ObjectMapper mapper = new ObjectMapper();
for(Object object : objects){
if(list.get(i) instanceof List){
MagicJsonMapper((List)list.get(i),object);
}
else{
objects[i] = mapper.convertValue(list.get(i), object.getClass());
}
i++;
}
//place -2 "objects" contains proper value of unitname
}
The issue is I am still not getting proper value in parameter after finished running this method. It means argument values are not retained as in contrast of normal java behaviour, is it something to do with variable argument.
Just for clarity I debugged the code and values are proper at the end of the function.
The objects array is created during the function call and discarded afterwards. If you need to access the values from the array after the call, you need to create the array explicitly.
Related
I am not getting the right answer when I try to use indexOf() of an ArrayList made up of user defined objects. Here is the code that creates one of the objects:
State kansas = new State("KS", 5570.81, 2000)
So, the name of the object is "kansas"
Here is the code that creates the ArrayList and adds the object:
ArrayList<State> allStates = new ArrayList<State>();
allStates.add(kansas);
And here is the code that I try to use to find the index of this object:
System.out.println(allStates.indexOf(kansas));
This is the point at which my compiler (Eclipse) throws me a red X indicating that there is a problem with my code and the problem is that it does not recognize 'kansas'. So I tried this:
String s = "kansas";
System.out.println(allStates.indexOf(s));
and it will run but the result is -1.
I am calling a method from a different class to create the ArrayList as opposed to creating it in the same class as my main method but I'm new enough to coding that I"m not sure if that is where I am going wrong. However, in order for the program that I am writing to work, I need to have data about each of the State objects stored so that I can access it from the main method.
Any advice?
*This is my first time posting a questions and I wasn't sure how much detail to go into so if I'm missing relevant information please let me know :)
method indexOf uses equlas() method to compare objects.
That why you have to override equals method in your custom class (if you planning use class in Map override hashCode method as well).
most IDE can generate these methods (equals and hashCode).
here simple example.
public class State {
private String stateCode;
public State(String stateCode /* other parameters*/) {
this.stateCode = stateCode;
}
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
State state = (State) o;
return stateCode.equals(state.stateCode);
}
#Override
public int hashCode() {
return stateCode.hashCode();
}
}
This is because, String is not your custom object State type. Your array list is a list of all 'State' types, which is why this -
String s = "kansas";
System.out.println(allStates.indexOf(s));
won't work.
What you can do is have a convenience method that iterates through the list and returns the index.
private int getIndexOfState(String stateName) {
for(State stateObject : allStates) {
if(stateObject.getName().equals(stateName))
return allStates.indexOf(stateObject);
}
return -1;
}
Now you can reuse this method to find index of any state name you pass, and whenever the method returns -1, it means the stateName(state) was not found in the list of states.You can pass in 'Kansas' or 'California' or anything as the parameter to the method.
In your method call you say
System.out.println(getIndexOfState("Kansas"));
System.out.println(getIndexOfState("Chicago"));
The return value is -1 because there is no String "kansas" in allStates, and ArrayList#indexOf returns -1 if the element is not present in the list. If you try to add s to allStates, the compiler won't even let you, because State is not a String.
I don't know why you instantiated a String with the value "kansas", but if you need to refer to the State from its name (maybe the name comes from a Scanner input), you will need a Map<String, State>, such as:
Map<String, State> map = new HashMap<>();
map.put("kansas", kansas) // a String and the object named kansas
Then, you can do:
System.out.println(allStates.indexOf(map.get("kansas")))
//or
String s = "kansas";
System.out.println(allStates.indexOf(map.get(s)))
I'm wondering if there is a way to Auto Cast an Object to some type by storing the Class type along with the object? I thought this was possible with Java, but maybe not.
For example:
class StorageItem
{
private int itemcount;
StorageItem(int itemcount)
{
this.itemcount = itemcount;
}
int getItemCount()
{
return itemcount;
}
}
class Storage
{
private Class clazz;
private Object value;
public Storage(Class clazz, Object value)
{
this.clazz = clazz;
this.value = value;
}
//Is there a way such a call can be created to automatically cast
//the object to the class type and return that cast type in a
//generic way. The idea being that Storage knows what it should
//already be cast to. Is this possible?
public T getValue()
{
return clazz.cast(value);
}
}
A usage example:
public static void main(String[] args)
{
//Create storage item
Storage storage = new Storage(StorageItem.class, new StorageItem(1234));
//The call to getValue() will automatically cast to the Class passed
//into Storage.
int itemcount = storage.getValue().getItemCount(); //returns 1234
}
Obviously the getValue() call in Storage is a pseudocode call, but it's just there to provide the idea as to what I would like to do.
Is there anyway to have a getValue() call that will Auto cast to the Class typed stored in the Storage class. Again, the idea is that the Storage class knows what it should be cast to. Or is there anyway this can be done at all?
StorageItem is just one simple example. Here, it just stores an int for discussion purposes. However, it could be more complex.
Another usage example, would be storing the Storage object in a list.
List<Storage> row = new ArrayList<Storage>();
row.add(new Storage(StorageItem.class, 1234));
row.add(new Storage(String.class, "Jason"));
row.add(new Storage(Integer.class, 30));
row.add(new Storage(Double.class, 12.7));
Then, these can be accessed in the following way.
//calls StorageItem's getItemCount() method
row.get(0).getValue().getItemCount(); //returns 1234
//calls String's length() method
row.get(1).getValue().length(); //returns 5
//calls Integer's intValue() method
row.get(2).getValue().intValue();
//calls Integer's doubleValue() method
row.get(3).getValue().doubleValue();
If getValue() only ever returned an Object, I would have to always cast to the specific Object manually. Instead, if I can store the cast class inside the Storage object, then Storage has enough information to know what to automatically cast the Object to on the getValue() call.
If this is doable in Java is the answer to the question I'm seeking. And if so, how?
Would this do the trick? Much less hacking is required:
class Storage<T> {
private T value;
public Storage(T value) {
this.value = value;
}
public T getValue() {
return value;
}
}
I don't really see the problem that you're trying to solve here. #bali182's answer does give you a "generic" way to store a reference - but storing the reference itself is just easier.
Consider what happens if you put two Storage instances, containing differently-typed references, into a collection:
List<Storage<SOMETHING>> storages = new ArrayList<>();
storages.add(new Storage<String>("Hello"));
storages.add(new Storage<Integer>(1));
So: what is SOMETHING? Well, it has to be ?, since that is the only type which satisfies both elements.
Now, when you iterate through the list to retrieve them, you have to deal with them as Object:
for (Storage<?> storage : storages) {
Object object = storage.getValue();
// ...
}
because you don't, in general, know what the type of the stored reference is for any given element. The concrete type of object will be the concrete type of the element - String and Integer, for the list above - but you can't make use of these different types without using some means to detect that type (e.g. if (object instanceof String)).
It would just have been easier if the references were stored directly in the list:
List<Object> objects = new ArrayList<>();
storages.add("Hello");
storages.add(1;
for (Object object : objects) {
// ...
}
You still would have to do something to detect the concrete type of object; you're just doing it without the extra layer of indirection.
Although the above example is for unrelated types, it's still easier to do it with the direct references if they are the same type:
List<String> objects = Arrays.asList("Hello", "World");
for (String object : objects) {
// ...
}
Now you don't need to do anything to know the concrete type (you might, if the elements were of a non-final class, and you wanted to handle some subclasses specially), but you've still avoided needing to dereference Storage.getValue() to get at a value that you could have directly instead.
I have a class and I am taking 2 instance form that like
List<MyClass> lstMyClassTemp;
List<MyClass> lstMyClass = new ArrayList<MyClass>();
after initial some value or change some thing in lstMyClass I will update the value of temp variable lstMyClassTemp by a function Update()
private void update1()
{
lstMyClassTemp = new ArrayList<MyClass>(lstMyClass);
}
now my problem is before I run update function when I change some value in the lstMyClass variable the value of lstMyClassTemp variable change immediately but it is not true
please let me know what part could made problem
Edit and Update
Thanks for your answers
your answers are useful in continue I get new error and problem when I am changing value in lstMyClass the value in the lstMyClassTemp change immediately which part can make a problem?
lstMyClassTemp = new ArrayList<MyClass>();
for (i = 0; i < lstMyClass.size; i++) {
lstMyClassTemp.add((MyClass)lstMyClass.get(i));
}
// ... other code ...
int rowIStr=0;
for (int j = 0; j < 5; j++) {
if(lstMyClassTemp .get(j).getTempName().equals(lstMyClassTemp.get(rowIStr).getName()))
lstMyClass.get(j).setName("Alex");
}
rowIStr++
// ... other code ...
update1();
The copy constructor of ArrayList only copies the direct contents of the ols ArrayList. It does not perform deep copies of the objects inside the ArrayList. Calling the copy contructor is the same as:
List<MyClass> lstMyClassTemp = new ArrayList<>();
for(MyClass m: lstMyClass){
lstMyClassTemp.add(m);
}
So the new ArrayList contains the same references to objects of the type MyClass as the old one, but still only references.
When you do this:
lstMyClassTemp= new ArrayList<MyClass>(lstMyClass);
you create an exact copy in lstMyClassTemp of the references to the objects in lstMyClass. So lstMyClassTemp and lstMyClass refer to different lists, but those two lists contain references to the same objects. Therefore, when you do:
lstMyClass.get(j).setName("Alex");
then you must remember that lstMyClass.get(j) returns a reference to the same object as lstMyClassTemp.get(j). Not a copy of the object, but the same actual object. Therefore, when you set the name of that object, you can see the changes by using both lstMyClass.get(j) and lstMyClassTemp.get(j), since they are the same object.
Your problem is that the creation method you used passes the reference to the variable instead of simply copying it. Since Java does not have pointers you will have to manually copy it yourself. Here's an example of how you might do that.
lstMyClassTemp = new ArrayList<MyClass>();
for (i = 0; i < lstMyClass.size; i++) {
lstMyClassTemp.add((MyClass)lstMyClass.get(i));
}
Finally I find a way that is easy and useful I am putting that here I hope it will be helpful for another time :)
public class MyClass implements Cloneable {
/** some method ***/
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
}
in main body code :
ArrayList<MyClass> lstMyClassTemp= new ArrayList<MyClass>();
ArrayList<MyClass> lstMyClass= new ArrayList<MyClass>();
for(MyClass m: lstMyClass){
lstMyClassTemp.add((MyClass)m.clone());
}
the main part is cloning
image description here
I am new to java and I was writing some code to practice, but there is something that I am confused about. I have the following code:
public class test {
public static void main(String[]args) {
int n = 0;
ArrayList<String> fruits = new ArrayList();
setList(fruits);
n =setInt(9);
// get the values from fruits
for (String value: fruits) {
print(value);
}
}
public static void setList( ArrayList list) {
list.add("pear");
list.add("apple");
list.add("pear");
}
public static int setInt(int number) {
number = 3;
return number;
}
}
My question is why in order to set my Arraylist() there is no need to return the any value, but in order to set my int I need to return something.If run this code it prints all the values in my list, but I expected not to print anything because In my method setList I do not return any value. If I did not return any value with my setInt, the value of n would not change, and that makes sense to me.
Thank you.
There are different ways to that params get passed in functions. The usuall way that most beginners start with is pass by value. The other way is pass by reference. In passing by reference, the object itself is pass in, not a copy as is with pass by value. That means any changes will affect the param and remain, even after it is called. All objects in java are passed by reference, only primitives are passed by value. Thus, is why you don't have to return when using arraylist object.
Edit: Actually, I've made an error. What is actually occuring is that a copy of the reference itself is being passed by value. Take a look at this.
Everything in Java is Pass by Value.
With a third party API I observed the following.
Instead of using,
public static string getString(){
return "Hello World";
}
it uses something like
public static void getString(String output){
}
and I am getting the "output" string assigned.
I am curious about the reason of implementing such functionality. What are the advantages of using such output parameters?
Something isn't right in your example.
class Foo {
public static void main(String[] args) {
String x = "foo";
getString(x);
System.out.println(x);
}
public static void getString(String output){
output = "Hello World"
}
}
In the above program, the string "foo" will be output, not "Hello World".
Some types are mutable, in which case you can modify an object passed into a function. For immutable types (such as String), you would have to build some sort of wrapper class that you can pass around instead:
class Holder<T> {
public Holder(T value) {
this.value = value;
}
public T value;
}
Then you can instead pass around the holder:
public static void main(String[] args) {
String x = "foo";
Holder<String> h = new Holder(x);
getString(h);
System.out.println(h.value);
}
public static void getString(Holder<String> output){
output.value = "Hello World"
}
That example is wrong, Java does not have output parameters.
One thing you could do to emulate this behaviour is:
public void doSomething(String[] output) {
output[0] = "Hello World!";
}
But IMHO this sucks on multiple levels. :)
If you want a method to return something, make it return it. If you need to return multiple objects, create a container class to put these objects into and return that.
I disagree with Jasper: "In my opinion, this is a really ugly and bad way to return more than one result".
In .NET there is a interesting construct that utilize the output parameters:
bool IDictionary.TryGet(key, out value);
I find it very usefull and elegant. And it is the most convenient way to aks if an item is in collection and return it at the same time. With it you may write:
object obj;
if (myList.TryGet(theKey, out obj))
{
... work with the obj;
}
I constantly scold my developers if I see old-style code like:
if (myList.Contains(theKey))
{
obj = myList.Get(theKey);
}
You see, it cuts the performance in half. In Java there is no way to differentiate null value of an existing item from non-existance of an item in a Map in one call. Sometimes this is necessary.
This functionality has one big disadvantage - it doesn't work. Function parameters are local to function and assigning to them doesn't have any impact outside the function.
On the other hand
void getString(StringBuilder builder) {
builder.delete(0, builder.length());
builder.append("hello world");
}
will work, but I see no advantages of doing this (except when you need to return more than one value).
Sometimes this mechanism can avoid creation of a new object.
Example:
If an appropriate object exists anyhow, it is faster to pass it to the method and get some field changed.
This is more efficient than creating a new object inside the called method, and returning and assigning its reference (producing garbage that needs to be collected sometime).
String are immutable, you cannot use Java's pseudo output parameters with immutable objects.
Also, the scope of output is limited to the getString method. If you change the output variable, the caller won't see a thing.
What you can do, however, is change the state of the parameter. Consider the following example:
void handle(Request r) {
doStuff(r.getContent());
r.changeState("foobar");
r.setHandled();
}
If you have a manager calling multiple handles with a single Request, you can change the state of the Request to allow further processing (by other handlers) on a modified content. The manager could also decide to stop processing.
Advantages:
You don't need to return a special object containing the new content and whether the processing should stop. That object would only be used once and creating the object waste memory and processing power.
You don't have to create another Request object and let the garbage collector get rid of the now obsolete old reference.
In some cases, you can't create a new object. For example, because that object was created using a factory, and you don't have access to it, or because the object had listeners and you don't know how to tell the objects that were listening to the old Request that they should instead listen to the new Request.
Actually, it is impossible to have out parameters in java but you can make a work around making the method take on a de-reference for the immutable String and primitives by either writing a generic class where the immutable is the generic with the value and setter and getter or by using an array where element 0 (1 in length) is the value provided it is instantiate first because there are situations where you need to return more than one value where having to write a class just to return them where the class is only used there is just a waste of text and not really re-usable.
Now being a C/C++ and also .Net (mono or MS), it urges me that java does not support at least a de-reference for primitives; so, I resort to the array instead.
Here is an example. Let's say you need to create a function (method) to check whether the index is valid in the array but you also want to return the remainding length after the index is validated. Let's call it in c as 'bool validate_index(int index, int arr_len, int&rem)'. A way to do this in java would be 'Boolean validate_index(int index, int arr_len, int[] rem1)'. rem1 just means the array hold 1 element.
public static Boolean validate_index(int index, int arr_len, int[] rem1)
{
if (index < 0 || arr_len <= 0) return false;
Boolean retVal = (index >= 0 && index < arr_len);
if (retVal && rem1 != null) rem1[0] = (arr_len - (index + 1));
return retVal;
}
Now if we use this we can get both the Boolean return and the remainder.
public static void main(String[] args)
{
int[] ints = int[]{1, 2, 3, 4, 5, 6};
int[] aRem = int[]{-1};
//because we can only scapegoat the de-ref we need to instantiate it first.
Boolean result = validate_index(3, ints.length, aRem);
System.out.println("Validation = " + result.toString());
System.out.println("Remainding elements equals " + aRem[0].toString());
}
puts: Validation = True
puts: Remainding elements equals 2
Array elements always either point to the object on the stack or the address of the object on the heap. So using it as a de-references is absolutely possible even for arrays by making it a double array instantiating it as myArrayPointer = new Class[1][] then passing it in because sometimes you don't know what the length of the array will until the call going through an algorithm like 'Boolean tryToGetArray(SomeObject o, T[][] ppArray)' which would be the same as in c/c++ as 'template bool tryToGetArray (SomeObject* p, T** ppArray)' or C# 'bool tryToGetArray(SomeObject o, ref T[] array)'.
It works and it works well as long as the [][] or [] is instantiate in memory first with at least one element.
in my opinion, this is useful when you have more than one result in a function.