从对象列表中选择具有相同值的对象项

时间:2014-05-18 16:53:07

标签: java arrays list

我有一个数组或列表,其中包含时间戳,Id和其他数据。 像这样:

public class CanMessage {
    public int MsgID ;
    public byte length ;
    public byte [] dataByte = new byte[8];

}

public class CanTrace {
    public float timestamp ;
    public CanMessage canMsg ;
}

问题是如何制作CanTrace列表或数组,我可以在其中选择具有特定MsgID的List项目。因此,例如,我可以使用一个相同的MsgID创建dataByte的图。 或者这只能通过使用while循环搜索来实现,例如使用ct对象创建 List ct = new ArrayList();

3 个答案:

答案 0 :(得分:0)

如果MsgID是唯一的,那么使用带有键值对的HashMap(MsgID,CanTrace)会很有用 然后你就可以使用 - 访问dataByte了 - (CanTrace)(map.get(的MsgID))。数据字节

答案 1 :(得分:0)

如果您使用的是Java 8,则可以直接将过滤方法用作listOfCanMessages.stream().filter(b -> b.MsgID == 1)

在其他情况下,您可以尝试GuavaLamdaj

例如。

import static ch.lambdaj.Lambda.having;
import static ch.lambdaj.Lambda.on;
import static ch.lambdaj.Lambda.select;
import static org.hamcrest.core.IsEqual.equalTo;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import com.google.common.base.Predicate;
import com.google.common.collect.Collections2;
import com.google.common.collect.Lists;

public class FilterSample {

    public static void main(String[] args) {
        List<CanMessage> list = new ArrayList<CanMessage>();
        CanMessage c = new CanMessage();
        c.MsgID = 1;
        CanMessage c2 = new CanMessage();
        c2.MsgID = 2;
        CanMessage c3 = new CanMessage();
        c3.MsgID = 1;
        CanMessage c4 = new CanMessage();
        c4.MsgID = 4;

        list.add(c);
        list.add(c2);
        list.add(c3);
        list.add(c4);

        //Java 8 example
        List<CanMessage> filteredList1 = list.stream().filter(b -> b.MsgID == 1).collect(Collectors.toList());
        System.out.println(filteredList1);

        //Guava example
        List<CanMessage> filteredList2 = Lists.newArrayList(Collections2.filter(
                list, new Predicate<CanMessage>() {
                @Override
                public boolean apply(CanMessage input) {
                    if (input.MsgID == 1) {
                    return true;
                    }
                    return false;
                }
                }));
        System.out.println(filteredList2);

        //Lambdaj example. Please note  6 down vote accepted Lambdaj wraps your (non-final) classes with a Proxy 
        // and intercepts METHOD invocations on them. That means it cannot work on fields but only on methods. So 
        // you cannot access MsgID directly, you'll have to provide a getter method
        List<CanMessage> filteredList3 = select(list, having(on(CanMessage.class).getMsgID(), equalTo(1)));
        System.out.println(filteredList3);
    }

}

答案 2 :(得分:0)

感谢第一个答案。 我问一位同事,他带来了这个想法:

public void OrderedMsg(int Id){

    List<CanTrace> traces = new ArrayList<CanTrace>();

    Comparator<CanTrace> comparator = new Comparator<CanTrace>() {
        public int compare(CanTrace o1, CanTrace o2) {
            if (o1.time < o2.time) {
                return -1;
            } else if (o1.time > o2.time) {
                return 1;
            } else {
                return 0;
            }
        }
    };

    for (CanTrace trace : traces) {
        int id = trace.canMsg.MsgID;
        if (!orderedMap.containsKey(id)) {
            orderedMap.put(id, new TreeSet<CanTrace>(comparator));
        }
        orderedMap.get(id).add(trace);
    }


}