【问题标题】:ArrayList get all values for an object propertyArrayList 获取对象属性的所有值
【发布时间】:2013-12-03 18:09:49
【问题描述】:

假设我有一个对象 User 的 ArrayList,所以 ArrayList<user>。一个用户对象有一个属性userID

与其自己迭代列表并将用户 ID 添加到单独的列表中,是否有 API 调用可以将我想要的该对象上的属性传递给它,并将这些属性的列表返回给我?浏览了 API 并没有什么突出的。

在 Java 7 中寻找解决方案或 <.>

【问题讨论】:

    标签: java arraylist


    【解决方案1】:

    您可以使用lambdas expressions (Java 8) 来做到这一点:

    import java.util.*;
    import java.util.function.*;
    import java.util.stream.*;
    
    public class Test {
      public static void main(String args[]){
        List<User> users = Arrays.asList(new User(1,"Alice"), new User(2,"Bob"), new User(3,"Charlie"), new User(4,"Dave"));
        List<Long> listUsersId = users.stream()
                                      .map(u -> u.id)
                                      .collect(Collectors.toList());
        System.out.println(listUsersId);
      }
    }
    
    class User {
      public long id;
      public String name;
    
      public User(long id, String name){
        this.id = id;
        this.name = name;
      }
    }
    

    输出:

    [1, 2, 3, 4]
    

    片段here.


    使用反射的最丑陋的解决方案:
    public class Test {
        public static void main (String[] args) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
             List<User> users = Arrays.asList(new User(1,"Alice"), new User(2,"Bob"), new User(3,"Charlie"), new User(4,"Dave"));
             List<Object> list = get(users,"id");
             System.out.println(list);
        }
    
        public static List<Object> get(List<User> l, String fieldName) throws NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException{
            Field field = User.class.getDeclaredField(fieldName);
            field.setAccessible(true);
            List<Object> list = new ArrayList<>();
            for(User u : l){
                list.add(field.get(u));
            }
            field.setAccessible(false);
            return list;
        }
    }
    class User {
          private long id;
          private String name;
    
          public User(long id, String name){
            this.id = id;
            this.name = name;
          }
    }
    

    输出:

    [1, 2, 3, 4]
    

    【讨论】:

    • 有趣,不幸的是我们没有运行 8,但很高兴知道这即将到来。Java 7 或 的任何解决方案
    • @Michael 没有。但是你想构建一个可以返回一个字段列表的方法吗? List&lt;Object&gt; get(List&lt;User&gt; l, String fieldName) 之类的东西?
    • @Michael 我添加了一个使用反射的解决方案。您可以获得所有用户想要的属性列表,您只需提供要收集数据的字段的正确名称。请注意,我不太喜欢这种解决方案。
    【解决方案2】:

    您可以使用 Guava 的 Collections2#transform 方法获得相同的结果。

    List<Integer> userIDs = Collections2.transform(users, new Function<User, Integer> (){
                                public Integer apply(User user) {
                                       return user.getUserID();
                                }
                            });
    

    Guava 支持 Java 7 及更低版本,因此如果您想使用外部库,上述方法适用于您的情况。

    不幸的是,您将不得不对您可能拥有的任何其他对象及其内部字段执行类似的逻辑。它不像反射那样是一种通用的解决方案,它只是一种更紧凑的解决方案。

    【讨论】:

      【解决方案3】:

      听起来您想使用Map

      地图使用Key, Value 对。您可以将userID 指定为键,将实际的user 对象指定为值。

      You can read more here

      【讨论】:

      • 没错,唯一的问题是对象是使用 Jackson 从 json 映射的,所以希望让代码更简单一些。
      • 比哈希映射更简单?我不确定你在期待什么。实现起来非常简单。
      • 我认为你没有抓住重点。杰克逊很容易解析成一个列表。解析成 Map 会增加代码的复杂性。
      猜你喜欢
      • 2014-12-24
      • 2011-04-09
      • 1970-01-01
      • 2011-09-20
      • 2012-01-28
      • 2021-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多