Suppose I have a class that has a lot of different fields. This class is a DTO and for testing purposes, I do not care about actual values, just it exists. Is there any tool that can traverse through all fields and set primitives, 0 for Number (0.0 for Float, Double, 0 for Integer, 0L for Long, but not null as default), something like "test" for String?
Also, I want that tool to populate Collections (List, Set, Map).
Just a small googling provide this results:
EasyRandom simple to use modern java solution, formerly known as Random beans
EasyRandom for Java 6, formerly known as JPopulator.
PODAM with a
tutorial
else you can use reflection to populate:
primitive/wrapper with default value
string with rendom value
Collection<T>(set,list) with random size and re-using code to
populate <T>
and so on.
Else XML binding (with jaxb or other technology) can be an option but needs to prepare xml with data in advance.
Except frameworks all other solutions have two big issues: needs to be written and a lot of testing!
If you are using primitives ,they will be automatically set to their default values. In case of Wrapper calss, if you do not care about actual values, you might leave them to null. You can throw a NullPointerException if they are accessed without initializing them.
For populating it in the list, the simplest way should be create a object of class and adding objects to the list.
class DTO
{
int a;
String b;
float c;
DTO (int a,String b,float c)
{
this.a=a;
this.b=b;
this.c=c;
}
public static void main (String args[])
{
List <DTO> list = new ArrayList<DTO>();
DTO o = new DTO (1,"Test",11.3f);
list.add(o);
}
}
Printing the list and overriding toString() should display the values.
Write a method with Introspector.getBeanInfo(object.getClass()).getPropertyDescriptors() in a small loop to fill fields as needed. You can recursively call this method to fill classes, collections etc.
Other way is a XML deserialization using JAXB, XStream or Abraxas.
Is there any tool that can traversal through all fields and set primitives, 0 for Number (0.0 for Float, Double, 0 for Integer, 0L for Long, but not null as default), something like "test" for String? Also I want that tool to populate Collections (List, Set, Map).
AFAIK, there is nothing that will save you much effort over doing it the simple way. It is a trivial matter to declare the fields with an initializer, or to do some simple default initialization in the constructor(s).
It is probably a good idea to use primitive types rather than wrapper types; e.g. int rather Integer. One advantage is that fields with primitive types are default initialized to 0, 0.0 or false ... saving you the bother.
You can get the type of the field by reflection, and then initialize it to whatever you want, also using reflection.
public static void main(String[] args) {
MyDTO myDTO = new MyDTO();
Field [] fields = myDTO.getClass().getDeclaredFields();
for (Field field: fields){
if (field.getType().equals(Integer.TYPE)){
//Primitives are already initialized to 0, so no need to do anything.
}else if (field.getType().equals(String.class)){
System.out.println("String");
//Invoke setter method with reflection, initialize to ""
}
}
}
Related
For instance I have two Arraylists with different data types.
ArrayList<Integer> intValues = new ArrayList<Integer>();
intValues.add(1);
intValues.add(2);
intValues.add(3);
ArrayList<String> strValues = new ArrayList<String>();
strValues.add("4");
strValues.add("5");
strValues.add("6");
If both of these lists contained the same data type objects, I would easily call addAll function;
intValues.addAll(intValues2);
But of course if I try to call addAll function with these different type lists, compiler warns me with incompatible types: ArrayList cannot be converted to Collection<? extends Integer> warning.
So I have to create a bad solution like;
for(String s: strValues)
{
intValues.add(Integer.parseInt(s));
}
Is there a better way to do this, I mean, creating a class which implements List, overriding addAll function etc. so I will be able to call;
intValues.addAll(strValues);
And intValues list will contain 1,2,3,4,5,6.
Edit: I really don't want to store String values in an Integer array, I have to deal with some creepy old code at the moment and I need a Collection to hold some differend kinds of classes, trying to create a Constructor for those objects, this integer-string scenario is just a simple way to introduce my problem.
Let me tell you about my current situation with another integer-string like scenario:
Creepy class A is car, it holds car's weight, price, color, engine type.
Creepy class B is watch, it holds watch's still type, movement type, price, lug size etc.
I am trying to create a holder class, so it will hold those classes and adding a few functions (for example, overriding compare method makes the holder class to compare prices of different classes).
Now I think I have to create a HolderHolder class which implements List so I can call holderHolder.addAll(carsList) and holderHolder.addAll(watchesList), and it will hold these as Holder objects and yes, this does not look pretty.
You act as if what you want is self-evident and logical. It really isn't. "4" and 4 are entirely unrelated, and expecting that your list of integers now has a value 4 when you call addAll with "4" is, as a consequence, as bizarre as expecting your list of movies to gain 'Forrest Gump' when you call .addAll(colorsOfTheRainbow) on that, because in your mind, 'green' is so incredibly similar to 'Forrest Gump', that you might as well assume that. (Here, 'green' is "4" and 'Forrest Gump' is 4).
So let's do some work and make this more sensible:
That 'assumption' (that "4" is so similar to 4, that you want .add("4") to just mean that 4 shows up in your list) needs to encoded, explicitly, in your code. Now it makes sense, and now you can write a function that maps Green to Forrest Gump and use it for that example just the same - we've generalized the principle.
What you're really talking about is a mapping function that maps an element of your List<String> (so.. a String) to a type that your target list is of (Integer), and you then want the operation: Take this list. Map every value in it with my mapping function. Then, add all the mapped values to this other list.
That makes perfect sense.
So, write that.
List<Integer> intValues = ...;
strValues.map(Integer::valueOf).forEachOrdered(intValues::add);
Looks like bad smell.
One bad Solution can be an own implementation of an List with Type Object. But than you have to cast and work with the Classes of the primitive types.
I think i every case you have to parse or cast. That cost to much of performance just for easy call of addAll.
I would think about the incoming data and why they have to be the same but in different types?
Edit:
If i get to know it correct. It is a little bit hard to understand without more detailed infos.
But maybe you can write an mapper class to map thoose old creepy classes in one new class an then you can put these new class in an collection and can compare all by overriding equals.
public class CreepyClassMapper
{
public CreepyClassMapper(Car aCar, Watch aWatch)
{
}
#override
private boolean equals(Object obj)
{
// maybe add an instance check
CreepyClassMapper other = (CreepyClassMapper) object;
// do your compare stuff
return true;
}
}
if i were you, i will create a function like this in util class
public void append(ArrayList<Integer> intValues, ArrayList<String> strValues){
}
I have a method that needs to operate on a very general message. It receives an Object. I can determine if the Object is an array with:
obj.getClass().isArray()
but after that I need to find what the type of the array elements are.
My code will ultimately be passing data one element at a time to a system that will be re-building it's own data structure and I need to tell it what type it should be using. E.g. imagine a JSON or XML message to something else and I need to tell that service how it should treat the data that was given to it in the message:
long [] data = { 42 };
processObject(data);
void processObject(Object obj) { ... }
will produce something like:
<msg>
<value>42</value>
<type>LONG</type>
</msg>
There is only one int type in all of java, which therefore means there is only one int[] type. Thus, it is as simple as:
if (obj instanceof int[]) {
doSomethingWithIntArray((int[]) obj);
}
Or if you somehow want it in terms of class: if (obj.getClass() == int[].class) {.
If you want an enum, it's a simple matter of 8 if/elseifs. You can also make: Map<Class<?>, EnumType>, loading it up with a static initializer / using Map.of`:
private static final Map<Class<?>, EnumType> TYPES = Map.of(
int[].class, EnumType.INT,
byte[].class, EnumType.BYTE,
....);
and then you can call EnumType primitiveType = TYPES.get(obj.getClass()); which returns null if it's not a primitive array, and the EnumType you wanted if it is.
The if/elseif seems less efficient (8 steps, instead of the 1 step that TYPES.get would do), but is probably an order of magnitude or two faster. Far less overhead, CPUs pipeline, 8 chained ifs is nothing.
You want 'most efficient' and then talk about JSON and XML. Two formats that are quite, to notoriously, inefficient.
If you want to improve throughput and the like, you're barking up the wrong tree here. Making the java mode more efficient is going to speed up the process by at most 0.00000001%. Use a protocol designed for fast throughput (such as protobuf or something else binary oriented) if efficiency is what you're after.
I'm doing a project in Java in which I'm looking at the frequency characters occur after each other character in a text. When I'm collecting my results, I'm storing them in a 2d array of ints. However, in the same results table, I want to store some results about the whole thing.
Is it possible to have an array where some of the elements are arrays, and others are primitives?
Yes, you can have Object[] and store a mix a types, although it would have to be the wrapper Integer (not the primitive int). (Note: you could "cheat" and save each int as a single-element array int[], thus making it an Object, but "don't try this at home")
But even if you could, an array isn't the right approach. Instead, create a class for this.
Try something like this:
public class FrequencyAnalysis {
private int[] frequencies;
private String info;
private Date lastRun;
// etc
}
No, it is not working. There can only be objects OR primitives in one array. Anything else is just a workaround.
In that case you would have to store Objects (primitives will autobox to Wrapper classes) and then when you read the entries you would need to instanceof the Object and then cast it safely.
You can use boxed types, i.e. java.lang.Integer (So your array type must be Object[]), but better do make a new class for results Storage
In which case should you use primitive types(int) or reference types (Integer)?
This question sparked my curiosity.
In which case should you use primitive
types(int) or reference types
(Integer)?
As a rule of thumb, I will use a primitive (such as int) unless I have to use a class that wraps a primitive.
One of the cases were one must use a wrapper class such as Integer is in the case of using generics, as Java does not support the use of primitive types as type parameters:
List<int> intList = new ArrayList<int>(); // Not allowed.
List<Integer> integerList = new ArrayList<Integer>(); // Allowed.
And, in many cases, I will take advantage of autoboxing and unboxing, so I don't have to explicitly perform conversions from primitives to its wrapper class and vice versa:
// Autoboxing will turn "1", "2", "3" into Integers from ints.
List<Integer> numbers = Arrays.asList(1, 2, 3);
int sum = 0;
// Integers from the "numbers" List is unboxed into ints.
for (int number : numbers) {
sum += number;
}
Also, as an additional note, when converting from primitives to its wrapper class objects, and unique instances of objects are not necessary, use the valueOf method provided by the wrapper method, as it performs caching and return the same instance for a certain value, reducing the number of objects which are created:
Integer i1 = Integer.valueOf(1); // Prefer this.
Integer i2 = new Integer(1); // Avoid if not necessary.
For more information on the valueOf methods, the API specification for the Integer.valueOf method can serve as a reference for how those methods will behave in the wrapper classes for primitives.
That really depends on the context. First prefer the primitive, because it's more intuitive and has less overhead. If it is not possible for generics/autoboxing reasons, or if you want it to be nullable, then go for the wrapper type (complex type as you call it).
The general rules I follow when creating an API can be summarized as follows:
If the method must return an value, use a primitive type
If the method may not always apply (eg: getRadioId(...) on an object where such an ID may not exist), then return an Integer and specify in the JavaDocs that the method will return null in some cases.
On #2, look out for NPEs when autoboxing. If you have a method defined as:
public Integer getValue();
And then call it as follows:
int myValue = getValue();
In the case where getValue() returns null you'll get an NPE without an obvious cause.
Since Java does something called auto-boxing and auto-unboxing, you should use the primitive type int in most cases because of less overhead.
The only time you absolutely need to use Integer is in generics.
List<int> list; // won't compile
List<Integer> list; // correct
One case in which Integer might be prefered is when you are working with a database where numerical entries are allowed to be null, since you wouldn't be able to represent a null value with an int.
But of course if you're doing straight math, then int would be better as others have mentioned due to intuitiveness and less overhead.
My rule of thumb is: use boxed primitives only when it's necessary to get the code to compile. The only places in your code where the names of the primitive wrapper classes should appear is in generic type parameters and static method calls:
List<Integer> intList = new ArrayList<Integer>();
int n = Integer.parseInt("123");
That's the advice I would give to new Java programmers. As they learn more, they'll run into situations where they have to be more discerning, like when dealing with Maps or databases, but by then they should also have a better understanding of the difference between primitives and boxed primitives.
Autoboxing tempts us to believe int and Integer (for example) are interchangeable, but it's a trap. If you mix the two kinds of value indiscriminately, you can end up comparing two Integer values with == or trying to unbox a null without realizing it. The resulting bugs can be intermittent and difficult to track down.
It doesn't help that comparing boxed primitives with == sometimes works as if it were doing a value comparison. It's an illusion caused by the fact that values within a certain range are automatically cached in the process of autoboxing. It's the same problem we've always had with String values: comparing them with == sometimes "works" because you're actually comparing two references to the same, cached object.
When dealing with strings we can just tell the n00bs never to compare them with ==, as we've been doing all along. But comparing primitives with == is perfectly valid; the trick (thanks to autoboxing) is being sure the values really are primitives. The compiler will now let us declare a variable as an Integer and use it as if it were an int; that means we have to exercise a greater level of discipline and treat it as an error when someone does so without good reason.
Rather than calling them "complex types", you'd be best served thinking Integer, Double, etc. as "Classes", and int, double, etc. as "primitives".
If you're doing any type of sophisticated math, the Class-based numeric representation like Integer and Double will be cumbersome and slow you down - many math operations can only be done with primitives.
On the other hand, if you're trying to put your numbers into collections like Lists and Maps, those collections can only contain objects - and thus you must use (or convert to) classes like Integer and Double.
Personally, I use primitives whenever I can get away with it, and only convert to the Class representations like Integer when it's time to do input or output, and the transport requires those representations.
However, if you aren't doing any math at all, and instead are just passing the values straight through your code, you might save yourself some trouble by dealing with the Class-based forms (like Integer) exclusively.
I think this is a bit late but I wanted to add my opinion just in case.
in some scenarios, it's required to use the wrappers as the lack of a value is different from the default value.
example,
for one project I worked on, there was a field on screen where the user could enter a double value, the business requirement clearly mentioned that if the user enters a 0 the meaning is different from not entering a value and leaving the field blank and this difference will make an impact later on in a different module.
so in this scenario we had to use the Double object, since I cannot represent a lack of value using the primitive; since the primitive will default to 0 which was a valid input for the field.
I dont think there is any rule as such. I would choose the types over primitives (Integer over int) when I write method signatures, Maps, collections, Data Objects that get passed around. As such I would still like to use Integer instead of int even inside of methods etc. But if you think that is too much trouble (to type extra "eger") then it is okay to use ints for local variables.
If you want to setAttribute to session you have to use Object like Integer,Boolean,String in servlets. If you want to use value you can use primitive types. Objects may be null but primitives not. And if you want to compare types for primitives use == but objects use .equals because in object comparision == looks not values it looks if these are the same objects. And using primitives makes faster the code.
When we deal with Spring getRequest mapping methods, using boolean value does not work.
For instance :
#GetMapping("/goal")
public boolean isValidGoal() {
boolean isValid = true;
return isValid;
}
Always opt for Boolean in those cases.
Currently I'm using a HashMap<String, Integer> to map the strings to int and the int values need to be frequently accessed.
I'm looking for a better way to do this if possible with minimal object creation, and preferable being able to store the values as primitive ints without wrapping them with the Integer class.
(Basically, the reverse of the SparseArray's int->object mapping.)
Are they arbitrary values known at compile time? In that case, use a Java Enum or an Android Enum.
If you're using a HashMap there will be no way around using some object. If you're max value is 31 all values will be cached by the Integer implementation. There will be no object createion as long as you're using autoboxing or Integer.valueOf to access the Integer instances (not new Integer(..)).
If you want to minimize object creation you could write an mutable wrapper around a primitive int. One alternative is to (mis-)use java.util.concurrent.atomic.AtomicInteger which has some overhead.
Write a class like this:
public class Foo
{
public static final String A = "a";
public static final String B = "b";
public static int foo(String str)
{
final int val;
if(str == A || str.equals(A))
{
val = 0x01;
}
else if(str == B || str.equals(B))
{
val = 0x02;
}
// etc...
return (val);
}
}
You only create the Strings once each, the number of Strings are small enough that the .equals won't get called many times, and if you always us ethe constants then the .equals won't get called at all.
If you use a Map it will take more memory than this, and also given that the number of Strings is small the code above might be faster. Also you can refactor the implementation to use a Map internally (or an array, or whatever) and see what is the fastest/uses the least memory without having to change your API.
EDIT:
Another thing to look at is the proposal for switch with String... if this comes into the language (I think it is) and if Android adopts it, then you would be able to replace the code I have above with a switch without a performance hit. Essentially they do a switch on the hashCode and then only call .equals on objects that have the same hashCode. This does require that you figure out the hashCodes in advance, and that the hashCode always returns the same thing for ever (which it should since String defines the way hashCode must work).