【问题标题】:Performing Integers operation on List<Objects>对 List<Objects> 执行整数运算
【发布时间】:2017-05-05 05:43:34
【问题描述】:

我有一个 Objects 列表,我想将其转换为 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

将来自List&lt;Object&gt; 的不同数据类型的值添加到List&lt;Integer&gt; 可能是一个很好的自定义实现

  1. 可以根据长度附加字符串。
  2. 浮点数需要四舍五入

我知道How to cast an Object to an int in java? 的标准实现,但我正在寻找一个好的结构来编写一个通用的。

【问题讨论】:

  • 听起来您已经有了如何实施的计划。你有什么问题吗?
  • Java 8 似乎有一种使用流来处理类型转换的偷偷摸摸的方式。最初,我正在考虑编写可以处理不同instanceof 操作的方法。

标签: java list object type-conversion


【解决方案1】:

您可以使用流来处理Object 类型的列表,如以下代码所示(遵循 cmets):

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

浮点数需要四舍五入

您需要先使用floatValue()方法将Number值转换为float,然后应用Math.round,如上所示。

【讨论】:

  • 看起来棒极了。但是,您能否告诉我是否可以在此使用 Math.round 到最接近的十进制值?
  • 我已经更新了代码,看看使用Math.round
  • 感谢@javaguy 提供代码和解释(cmets)。 streams 很强大,我应该开始使用它们。
  • 是的,你是对的,它们非常强大,即它们提供干净/更简单的代码来处理数据
【解决方案2】:

如果您只想添加数字而不处理字符串,则可以使用:

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

如果您还想处理字符串,则需要将列表中的字符串替换为该长度的 int 值,然后如上所述进行处理。

【讨论】:

  • 好一个亚瑟。这就是为什么我正在考虑一个自定义实现,我可以将round 浮点数转换为nearest value
  • 感谢您的代码@Arthur。我希望我能接受关于 SO 的多个答案。
【解决方案3】:

instanceof 操作符会使这变得相对简单。

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
        }
    }
}

使用 Java 8,您可以使用 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());

【讨论】:

    【解决方案4】:

    这样你可以在添加到对象列表的同时添加到整数列表中

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-30
      • 2011-12-19
      • 2014-12-23
      相关资源
      最近更新 更多