Reputation: 2802
I have a List of Objects
which I want to convert to a List of Integers
List<Object> list = new ArrayList<>();
list.add("StringTest");
list.add(10);
list.add(5.9);
list.add(2.5f);
list.add(12L);
... // different datatypes
List<Integer> result = new ArrayList<>();
// convert items from list and add to result
What could be a good custom implementation to add values from different datatypes of List<Object>
to a List<Integer>
I know standard implmentation on How to cast an Object to an int in java? but I am looking for a good structure to write a generic one.
Upvotes: 3
Views: 876
Reputation: 99
If you want to add just numbers and don't process strings, than you can use this:
List<Object> list = new ArrayList<>();
list.add("StringTest");
list.add(10);
list.add(5.9);
list.add(2.5f);
list.add(12L);
List<Integer> result = new ArrayList<>();
list.stream().filter(element -> element instanceof Number)
.map(Number.class::cast)
.mapToDouble(Number::doubleValue)
.mapToLong(Math::round)
.mapToInt(Math::toIntExact) // can throw ArithmeticException if long value overflows an int
.forEach(result::add);
If you also want to process string, than you need to replace string in list with int values of there length and then process as mentioned above.
Upvotes: 2
Reputation: 22422
You can use streams to process the list of Object
types as shown in the below code (follow the comments):
//Collect all Number types to ints
List<Integer> output1 = list.stream().
filter(val -> !(val instanceof String)).//filter non-String types
map(val -> ((Number)val).floatValue()).//convert to Number & get float value
map(val -> (int)Math.round(val)).//apply Math.round
collect(Collectors.toList());//collect as List
//Collect all String types to int
List<Integer> output2 = list.stream().
filter(val -> (val instanceof String)).//filter String types
map(val -> (((String)val).length())).//get String lengths
collect(Collectors.toList());//collect as List
//Now, merge both the lists
output2.addAll(output1);
Floating numbers needs to be rounded
You need to first convert the Number
value to float
using floatValue()
method and then apply Math.round
as shown above.
Upvotes: 2
Reputation: 33466
The instanceof
operator would make this relatively simple.
public class Convert {
public static int toInt(Object o) {
if (o instanceof String) {
return ((String)o).length();
} else if (o instanceof Number) {
return Math.round(((Number)o).floatValue());
} else {
return o.hashCode(); // or throw an exception
}
}
}
With Java 8, you could convert the values with a Stream
.
List<Object> list = new ArrayList<>();
list.add("StringTest");
list.add(10);
list.add(5.9);
list.add(2.5f);
list.add(12L);
List<Integer> result = list.stream().map(Convert::toInt).collect(Collectors.toList());
Upvotes: 1
Reputation: 792
With this you can add to the Integer list at the same time when you add to the object list
final List<Integer> integerList=new ArrayList<Integer>();
List<Object> list=new ArrayList<Object>(){
public boolean add(Object e) {
if(e instanceof String){
integerList.add(((String)e).length());
}
if (e instanceof Float){
integerList.add(Math.round((float) e));
}
else{
// other cases
}
return super.add(e);
};
};
list.add("StringTest");
list.add(10);
list.add(5.9);
list.add(2.5f);
list.add(12L);
Upvotes: 0