This question already has an answer here:
Regarding Map having an value of type arraylist
(1 answer)
Closed 9 years ago.
I have a query, I have a method in my class named abc of which return type is of arraylist as shown below
public List<abcinfo> getabc(String fileIdentifier)
{}
Now in the same class inside another method I need to add the outcome of the above method in the form of key as
shown below
HashMap<String, Object> data = new HashMap<String, Object>();
data.put("GGG", getabc(String fileIdentifier));
Now I am directly calling the method name as a value please advise me is it the correct way
as all the things are in same class, Please advise
This will not compile as you are not exactly specifying a String object as an argument to the getabc method. Why are you specifying the type in his line? :
data.put("GGG", getabc(String fileIdentifier));
String identifier is not a valid argument. Pass a String argument or variable instead such as
data.put("GGG", getabc("ArgumentRelativeToTheContextOfYourMethod"));
Apart from that , there doesn't seem to be anything wrong with your code. (relative to what you asked)
The method or the method call being in the same class should not be a problem.
In your case , the HashMap will have an entry with key as GGG and value as a List returned by your getabc method.
The value however will need to be type casted to List as you have stored it as an Object
It's correct, you can call the methode inside your class (as well as outside since it is declared as public), but on reading the Object back you will have to cast it to List<abcinfo>.
Related
This question already has answers here:
Reference to an instance method of a particular object
(6 answers)
Closed 4 years ago.
I've seen a lot of methods where a new class is instantiated in a lambda method reference but can't seem to understand why. When is the new keyword needed in a method reference?
For example, the following passes compilation:
UnaryOperator<String>stringToUpperCase = String::toUpperCase;
But this doesn't:
UnaryOperator<String>stringToUpperCase = new String()::toUpperCase;
String::toUpperCase is a method reference that can be applied to any String instance.
new String()::toUpperCase is a method reference that can be applied to a specific String instance (the instance created by new String()).
Since UnaryOperator<String> expects a method that takes a String and returns a String, String::toUpperCase fits (since you can apply it on a String and get the upper case version of that String).
On the other hand, new String()::toUpperCase doesn't fit UnaryOperator<String>, since it is executed on an already specified String, so you can't pass another String instance to it.
It can, however, by assigned to a Supplier<String>, since it simply supplies an empty String instance:
Supplier<String> emptyStringToUpperCase = new String()::toUpperCase;
This is similar to:
Supplier<String> emptyStringToUpperCase = () -> new String().toUpperCase();
while this:
UnaryOperator<String> stringToUpperCase = String::toUpperCase;
is similar to:
UnaryOperator<String> stringToUpperCase = s -> s.toUpperCase();
There are four kinds of method references as shown below and your type falls in the second category, but UnaryOperator<String> essentially needs to represent a method which accepts any String argument and returns a String. However, the non-working method reference that you have used is actually working on a particular String object (i.e. not any String object)
Refer: https://docs.oracle.com/javase/tutorial/java/javaOO/methodreferences.html
This question already has answers here:
Why might one also use a blank constructor?
(10 answers)
Java entity - why do I need an empty constructor?
(8 answers)
Why Default constructor need to declare in POJO file which has Parameterized Constructor while instantiating Object?
(5 answers)
Default constructor does not initialize the instance members of the class?
(7 answers)
Closed 5 years ago.
Is it okay to use an empty constructor in Java? For example, when loading the data from a MySQL database, I want to do something like:
ResultSet set = statement.executeQuery();
while (set.next()) {
Faction faction = new Faction();
faction.setId(UUID.fromString(set.getString("id")));
faction.setName(set.getString("name"));
}
Because I already have a constructor for the faction class,
public Faction(Player player, UUID uuid) {}
I was wondering if I can have a plain constructor and just set the values as and when.
Otherwise I could create a constructor using parameters that match the mySQL data (public Faction(String name, UUID uuid, String announcement..etc), to load in.. Not sure what is best practice?
If the object state should not change when the Faction class is instantiated, provide a constructor with args and removing setter is better.
In this way, you avoid undesirable behavior.
Now, according to your saying, you probably need to set many String parameters.
Doing it with a constructor is very error prone as you may do a mistake in the parameter order when you use it.
To achieve your need, you have two main ways :
using an empty constructor and then setters as you propose (desirable if the object is mutable)
if your object is immutable, you could use the Builder pattern to construct an immutable object (You write something like : Faction faction = new Faction.Builder().name(name).uuid(uuid).announcement(announcement).build();
It depends on your use case. If you dont want the class variables to change once you set them then in that case declare those variables as final and use the parametised constructor. If you want the variables to change once you set them, then use the default constructor with setters and getters.Both the options are perfectly fine.
This question already has an answer here:
IllegalArgumentException with constructing class using reflection and array arguments
(1 answer)
Closed 6 years ago.
I am dumping CSV via jackson. I have a couple of mapping classes and want to pass the mapping class to the CSV export method.
I have an abstract class, extended it to each of the csv column formats. I pass the name of the class to the export function then want to map the data via the constructor for the class and dump it as CSV.
All fine until I get to creating the class that does the mapping and is to be exported.
Invocation exception/Invalid number of parameters exception.
protected String mapTransactionsToCSV(List<Object[]> results, String rowClassName)
Class rowClass = Class.forName(rowClassName);
for (Object[] component : results)
VehicleAbstract vehicle = (VehicleAbstract) rowClass.getDeclaredConstructor(Object[].class).newInstance(component);
csv.append(mapper.writer(schema).writeValueAsString(vehicle));
}
}
My specific class (and abstract class, which I just copied to try). has 2 constructors
public Bus() {}
public Bus(Object[] component) {}
See Problem with constructing class using reflection and array arguments
The problem is that newInstance already takes an array of objects. You need to wrap your object array in another array. Something like this:
component = {component}; // Wrap in a new object array
VehicleAbstract vehicle = (VehicleAbstract) rowClass.getDeclaredConstructor(Object[].class).newInstance(component);
This is the reason that you're getting an invalid number of parameters - you're passing each item in that object array as a separate parameter, instead of one parameter (the array of objects).
This question already has answers here:
Casting to a Class which is determined at run-time
(2 answers)
Closed 9 years ago.
I'm trying to use custom Class as a value in a Map<String, Class<?>>. Following are relevant parts of code:
Following is declaration and initialization of Map in main():
public static Map<String, Class<?>> mapQuery2ResponseType = new HashMap<String, Class<?>>();
static {
mapQuery2ResponseType.put("string1", CustomClass1.class);
mapQuery2ResponseType.put("string2", CustomClass2.class);
mapQuery2ResponseType.put("string3", CustomClass3.class);
}
Now I'm using this map to typecast an object to one of these classes: (assume that all classes contain a method getName() which return a String)
String name = (
(
mapQuery2ResponseType.get("string1")
)obj1
).getName();
where, obj1 is of generic type T,
but it's not allowing me to do so and says: Syntax error on token "obj1", delete this token.
Please help me to understand where am I doing wrong?
Edit:
When I use following code, it worked perfectly giving me the expected result,
String name = (
(
CustomClass1
)obj1
).getName();
and obj1 is of the same type as returned by mapQuery2ResponseType.put("string1", CustomClass1.class);.
Here I can see 1 thing... if I use use it directly, i use it as "CustomClass1", whereas if I get it from map by mapQuery2ResponseType.get("string1"), it returns "CustomClass1.class". I'm not sure if there is any difference in these two approaches? If there is, what is it?
So actually there wont be any conversion, it's just that I'm using it for large number of classes, and so trying to use a generalized approach.
Edit2:
as given in this question: Java: difference between “CustomClass1” and “CustomClass1.class”?, I think, reflection is the only solution for this task. But can anybody explain how to do it using reflection?
Simply put, this is syntactically invalid code. Not coincidentally, the compiler is telling you exactly what the problem is.
Remove ob1. I don't know what it is, or what you think it's supposed to do, but it does not make any sense there. To explain this, I'm going to twiddle your code just a bit:
The original code:
String name = ((mapQuery2ResponseType.get("string1"))obj1).getName();
Now with a local variable:
Class<?> clazz = mapQuery2ResponseType.get("string1");
String name = ((clazz) obj1).getName();
Okay, so now I think I see: you're trying to use a Class instance to cast an object. You can't do this – Java's syntax simply does not permit it. Here's how a cast might normally look:
Object foo = "bar";
String baz = (String) foo;
Note how the token for the cast expression is String, not String.class.
Class#cast() might look like a useful alternative, but that's not going to be of any use here, since you've only got Class<?>, and not Class<T>.
Forget about the Map. I suggest you restructure your code entirely such that the getName() method is defined on an interface which obj1 and all similar objects implement (assuming that the various objects have heterogenous types).
For example:
interface MyCommonInterface {
String getName();
}
class MyClass implements MyCommonInterface {
public String getName() {
// snip
}
}
// ...
MyClass obj1 = /* ... */
String name = obj1.getName();
No casting, no fancy Maps or Class instances. Just proper, simple use of the right parts of the language.
I think its better to use JAVA Reflection to do that.
Typecast needs the Type syntax befor the object to be cast, so you can do like this (CustomClass1.class)obj1, but you can't do it like (mapQuery2ResponseType.get("string1"))obj1 cause compiler can't take the cast in runtime environment.
When compile your code, you map value is considered as a value not a valid type, so you can't make cast like you have showed.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is Java pass-by-reference?
Does a List object get passed by reference? In other words, if I pass an ArrayList (java.util.ArrayList) object to a class, will it be automatically updated when I change it?
in other word: If I pass an ArrayList (java.util.ArrayList) object to a class, will it be automatically updated when I change it?
Yes
Does the List object passed by reference?
Value of reference would get passed
public updateList(List<String> names){
//..
}
Explanation
When you call updateList(someOtherList); the value of someOtherList which is a reference will copied to names (another reference in method, bit by bit) so now both of them are referring to same instance in memory and thus it will change
See
Is Java "pass-by-reference" or "pass-by-value"?
Yes, a List that you pass to a method is passed by reference. Any objects you add to the List inside the method will still be in the List after the method returns.
If you add to a list in one method, its original reference in first method will also contain the new item.
java is pass by value, and for objects this means the reference is passed by value.
Yes, because You just pass a reference of ArrayList-Object, to your Object.