Performing operations on integers in the <Objects> list
I have a list Objects
that I want to convert to a listIntegers
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 for adding values ββfrom different data types List<Object>
toList<Integer>
- Lines can be added depending on their length.
- Floating numbers must be rounded.
I know the standard binding to How to distinguish an object from an int in java? but I am looking for a good structure for writing general.
source share
You can use streams to process the list of types Object
as shown in the code below (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 must be rounded
You first need to convert the value Number
to float
using a method floatValue()
and then apply Math.round
as shown above.
source share
If you only want to add numbers and not process strings, 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 the string, then you need to replace the string in the list with int values ββthere of length and then process as above.
source share
The operator instanceof
will make this relatively easy.
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 can convert values ββusing 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());
source share
With this you can add to the list Integer at the same time while adding to the list of objects
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);
source share