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.

+3


source share


4 answers


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.

+2


source


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.

+2


source


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());

      

+1


source


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);

      

0


source







All Articles