在java中搜索列表中对象的最快方法

时间:2016-11-03 18:13:49

标签: java search parallel-processing hashmap

我有一个结构:

public class DataItem {
    public int wordID, categoryID, documentID, count;
}

我的列表如下:

final public ArrayList<DataItem> data = new ArrayList<>();

我写了一个搜索它的方法:

public DataItem FindDataItem(final int wordID, final int categoryID, final int documentID)
{
    for(DataItem dataItem : data)
        if(dataItem.wordID == wordID && dataItem.documentID == documentID && dataItem.categoryID == categoryID)
            return dataItem;
    return null;
}

但它太慢了。我怎样才能加快速度?

我在想彼此内部有四个 HashMap ,但是我想把这个数据用作数据库表,所以很难在 HashMap <中按计数进行分组/ p>

我也在考虑 ParalellStream ,但我不知道如何使用它。看起来很复杂但它仍然是O(n)。

我正在考虑使用数据库。但我不想拥有IO。我想把它全部放在内存中。

请指导我。

2 个答案:

答案 0 :(得分:0)

以下是如何使用并行流:

public DataItem FindDataItem(final int wordID, final int categoryID, final int documentID) {
    return data.parallelStream()
            .filter(dataItem -> dataItem.wordID == wordID
                    && dataItem.documentID == documentID
                    && dataItem.categoryID == categoryID)
            .findAny()
            .orElse(null);
}

就像你说的那样,它不会影响时间复杂度,但它可以根据可用的线程数加快操作。

答案 1 :(得分:0)

正如@ShreyasSarvothama在评论中所说,检索价值的最快方法是使用地图。

我认为你可以使用一个地图,其地图的密钥是用你的find方法的参数计算的(考虑到它们的组合给出了一个DataItem的唯一标识符)。

import java.util.*;
import java.util.stream.*;

public class Test {

    private class DataItem {
        public int wordID, categoryID, documentID, count;

        public DataItem(int w, int c, int d) {
            wordID = w;
            categoryID = c;
            documentID = d;
        }

        public String toString() {
            return "wordID:" + wordID + " categoryID:" + categoryID + " documentID:" + documentID;
        }
    }

    private Map<Integer, DataItem> map;

    public void setList(List<DataItem> list) {
        this.map = list.stream().collect(Collectors.toMap(dataItem -> dataItem.wordID * dataItem.categoryID * dataItem.documentID, dataItem -> dataItem));        
    }

    public DataItem getDataItem(int wordID, int categoryID, int documentID) {
        return map.get(wordID * categoryID * documentID);
    }

    public static void main(String[] args) {
        Test t = new Test();
        t.setList(Arrays.asList(t.new DataItem(1,2,3), t.new DataItem(2,3,4), t.new DataItem(3,3,4)));
        System.out.println(t.getDataItem(2,3,4));
    }
}

希望它有所帮助。