Java 处理列表中对象的属性?

Java 处理列表中对象的属性?,java,android,list,object,properties,Java,Android,List,Object,Properties,给定以下代码: public class MyObject { String myProperty; public MyObject(String propertyValue) { myProperty=propertyValue; } } 及 我知道任务A和B可以通过循环ArrayList来解决,但我想知道是否有更好的方法/Eclipse中已经内置了一些东西?谢谢你的提示:-) 请注意,我不想使用外部库(我目前正在android上开发,希望保持应用程序的小型化)。如果您需要第

给定以下代码:

public class MyObject { 

String myProperty;

public MyObject(String propertyValue) {
    myProperty=propertyValue; 
}
}

我知道任务A和B可以通过循环ArrayList来解决,但我想知道是否有更好的方法/Eclipse中已经内置了一些东西?谢谢你的提示:-)

请注意,我不想使用外部库(我目前正在android上开发,希望保持应用程序的小型化)。

如果您需要第一个库(任务A),它可能表明
ArrayList
不是您应该使用的最佳数据结构。这种类型的访问应该让您考虑使用<代码> map 或<代码> MultIMAP (实现)。 但是。。。如果你真的需要这种东西。有几个图书馆派上了用场

最近很流行。另一个似乎更专业:

// Task A
filter(having(on(MyObject.class).getPropertyValue(), equalTo("second")), objects);

// Task B
convert(objects, new PropertyExtractor("propertyValue"));
// or even
extract(objects, on(MyObject.class).getPropertyValue());
(我没有机会编译/运行我输入的代码,所以请不要太严格)

。。。但是让我们假设我正在寻找java中没有外部库的最佳方法

在这种情况下,最好的方法是编写循环

可以基于对命名字段的反射访问构建一个解决方案,但代码并不简单,而且肯定没有性能

。。。所以,如果我引进一个只用于一件小事的外部库,我想我会被我的队友杀死


你的同事也会因为你使用反射而杀了你。确保你的性腺仍然附着(:-)的情况下生存的最好方法是编写循环。

Eclipse不会直接帮助你完成这项任务-它只能帮助创建程序-它不会自己创建

如果不能向项目中添加新库,则可以编写自己的通用解决方案。然而,我强烈建议您考虑像前面建议的那样添加一些公共库,如Guava或ApacheCommons

您试图实现的两个任务可以更一般地描述为过滤和映射(也称为选择、投影)。 可以通过使用谓词(一个简单的函数,它将返回对象是否应包含在新集合中)来概括过滤。 映射可以通过一个通用函数实现,该函数接受一个源对象(在您的示例中为MyObject),并返回另一种类型的对象(在您的示例中为String)

这些集合(collection)操作更容易被语言支持,其中一些被编译到JVM中,比如python(jython)、groovy和scala。但我猜在这个项目中使用不同的语言是不可能的

因此,我将演示如何在Java中实现它,尽管语法有点笨拙,因为我们将使用匿名类作为谓词和转换器

这里有一个DIY过滤的简单示例,所以我将在示例中使用它

我们需要的两个接口:

public interface Convertor<FROM, TO> {
         TO convert(FROM from);
    }

public interface Predicate<T> {
    boolean apply(T type);
}
公共接口转换器{
转换(来自);
}
公共接口谓词{
布尔应用(T型);
}
而实际的“图书馆”:

import java.util.ArrayList;
导入java.util.Collection;
公共类集合{
公共静态集合选择(从集合、转换器或转换器){
收集结果=新建ArrayList();
for(FROM FROM项目:FROM){
result.add(convertor.convert(fromItem));
}
返回结果;
}
公共静态集合筛选器(集合目标、谓词){
收集结果=新建ArrayList();
for(T元素:目标){
if(谓词.apply(元素)){
结果:添加(元素);
}
}
返回结果;
}
}
现在我们可以轻松完成两项任务:

import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;

public class Main {

    public static void main(String[] args) {

        ArrayList<MyObject> objects = new ArrayList<MyObject>();
        objects.add(new MyObject("first"));
        objects.add(new MyObject("second"));
        objects.add(new MyObject("third"));

        // Now do Task A and Task B

        // Task A: Filter
        Collection<MyObject> filtered = CollectionUtils.filter(objects, new Predicate<MyObject>() {

            @Override
            public boolean apply(MyObject myObject) {
                return myObject.myProperty.equals("second");
            }
        });
        for (MyObject myObject: filtered) {System.out.println(myObject.myProperty);}
        System.out.println();

        // TASK B: Map/Select
        Collection<String> transforemd = CollectionUtils.select(objects, new Convertor<MyObject, String>() {

            @Override
            public String convert(MyObject from) {
                return from.myProperty;
            }
        });

        for (String str: transforemd) {System.out.println(str);}
    }
}
import java.util.ArrayList;
导入java.util.Collection;
导入java.util.LinkedList;
公共班机{
公共静态void main(字符串[]args){
ArrayList对象=新的ArrayList();
添加(新的MyObject(“第一”));
添加(新的MyObject(“第二”));
添加(新的MyObject(“第三”));
//现在执行任务A和任务B
//任务A:过滤器
Collection filtered=CollectionUtils.filter(对象,新谓词(){
@凌驾
公共布尔应用(MyObject MyObject){
返回myObject.myProperty.equals(“秒”);
}
});
对于(MyObject MyObject:filtered){System.out.println(MyObject.myProperty);}
System.out.println();
//任务B:映射/选择
Collection transforemd=CollectionUtils.select(对象,新转换器(){
@凌驾
公共字符串转换(MyObject-from){
从.myProperty返回;
}
});
for(String str:transforemd){System.out.println(str);}
}
}
现在更改谓词以过滤其他对象、创建不同的字符串甚至其他类型而不是脚本将非常简单:只需更改apply()和convert()函数!(哦,还有一些泛型提示:))


免责声明:代码没有经过彻底测试,只是为了演示而推出,可能还有其他一些问题(例如为新集合分配ArrayList)。这就是为什么使用经过良好测试和调试的第三方库通常更好

诚然,下面是我的作品的一点广告,但它确实适合你的问题

首先,必须有人做这项工作。要么你自己做,即自己写必要的循环,要么你有一些库为你做这项工作

我不知道这里建议的其他lib,但是如果您想看一看,这是我自己编写的一个小lib,许可证允许它从源代码中获取您需要的内容,并将其包含在您自己的源代码中

在这种方法中,使用了专门制作的
Grepper
s和
Mapper
s,因此不需要
// Task A
filter(having(on(MyObject.class).getPropertyValue(), equalTo("second")), objects);

// Task B
convert(objects, new PropertyExtractor("propertyValue"));
// or even
extract(objects, on(MyObject.class).getPropertyValue());
public interface Convertor<FROM, TO> {
         TO convert(FROM from);
    }

public interface Predicate<T> {
    boolean apply(T type);
}
import java.util.ArrayList;
import java.util.Collection;


public class CollectionUtils {
    public static <FROM, TO> Collection<TO> select(Collection<FROM> from, Convertor<FROM, TO> convertor) {
        Collection<TO> result = new ArrayList<TO>();
        for (FROM fromItem: from) {
            result.add(convertor.convert(fromItem));
        }
        return result;
    }

    public static <T> Collection<T> filter(Collection<T> target, Predicate<T> predicate) {
        Collection<T> result = new ArrayList<T>();
        for (T element: target) {
            if (predicate.apply(element)) {
                result.add(element);
            }
        }
        return result;
    }

}
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;

public class Main {

    public static void main(String[] args) {

        ArrayList<MyObject> objects = new ArrayList<MyObject>();
        objects.add(new MyObject("first"));
        objects.add(new MyObject("second"));
        objects.add(new MyObject("third"));

        // Now do Task A and Task B

        // Task A: Filter
        Collection<MyObject> filtered = CollectionUtils.filter(objects, new Predicate<MyObject>() {

            @Override
            public boolean apply(MyObject myObject) {
                return myObject.myProperty.equals("second");
            }
        });
        for (MyObject myObject: filtered) {System.out.println(myObject.myProperty);}
        System.out.println();

        // TASK B: Map/Select
        Collection<String> transforemd = CollectionUtils.select(objects, new Convertor<MyObject, String>() {

            @Override
            public String convert(MyObject from) {
                return from.myProperty;
            }
        });

        for (String str: transforemd) {System.out.println(str);}
    }
}
ArrayList<MyObject> filteredObjects = objects.findPropertyValue(myProperty, "second") ?
import org.tbull.util.Collections;
import org.tbull.util.Grepper;

private static class PropertyGrepper implements Grepper<MyObject> {
    public final String property;
    public PropertyGrepper(String property) {
        this.property = property;
    }
    public @Override boolean grep(MyObject element) {
        return element.myProperty.equals(property);
    }
}

List<MyObject> filteredObjects = Collections.grep(new PropertyGrepper("second"), objects);
ArrayList propertyValues = objects.getPropertyValues(myProperty) ?
import org.tbull.util.Collections;
import org.tbull.util.Mapper;

private static class PropertyExtractor implements Mapper<MyObject, String> {
    public @Override String map(MyObject element) {
        return element.myProperty;
    }
}

List<String> propertyValues = Collections.map(new PropertyExtractor(), objects);