Java什么是按关键字搜索对象的最佳数据结构

时间:2014-06-25 17:01:28

标签: java data-structures keyword-search

假设我有一个“期刊文章”类,其中包含年份,作者,标题,期刊名称,关键字等变量。

作者和关键字等变量可能会被声明为 String []作者 String []关键字

通过一个或多个“关键字”,或几个作者姓名中的一个或标题的一部分,在“期刊论文”的一组对象中搜索的最佳数据结构是什么?

谢谢!

=============================================== =========================== 在每个人的帮助下,通过Processing环境实现的测试代码如下所示。建议非常感谢!谢谢!

ArrayList<Paper> papers = new ArrayList<Paper>();

HashMap<String, ArrayList<Paper>> hm = new HashMap<String, ArrayList<Paper>>();

void setup(){
  Paper paperA = new Paper();
  paperA.title = "paperA";
  paperA.keywords.append("cat");
  paperA.keywords.append("dog");
  paperA.keywords.append("egg");
  //println(paperA.keywords);
  papers.add(paperA);

  Paper paperC = new Paper();
  paperC.title = "paperC";
  paperC.keywords.append("egg");
  paperC.keywords.append("cat");
  //println(paperC.keywords);
  papers.add(paperC);

  Paper paperB = new Paper();
  paperB.title = "paperB";
  paperB.keywords.append("dog");
  paperB.keywords.append("egg");
  //println(paperB.keywords); 
  papers.add(paperB);

  for (Paper p : papers) {
    // get a list of keywords for the current paper
    StringList keywords = p.keywords;

    // go through each keyword of the current paper
    for (int i=0; i<keywords.size(); i++) {
      String keyword = keywords.get(i);

      if ( hm.containsKey(keyword) ) { 
        // if the hashmap has this keyword
        // get the current paper list associated with this keyword
        // which is the "value" of this keyword
        ArrayList<Paper> papers = hm.get(keyword);        
        papers.add(p); // add the current paper to the paper list        
        hm.put(keyword, papers); // put the keyword and its paper list back to hashmap
      } else { 
        // if the hashmap doesn't have this keyword
        // create a new Arraylist to store the papers with this keyword
        ArrayList<Paper> papers = new ArrayList<Paper>();        
        papers.add(p); // add the current paper to this ArrayList        
        hm.put(keyword, papers); // put this new keyword and its paper list to hashmap
      }
    }

  }

  ArrayList<Paper> paperList = new ArrayList<Paper>();
  paperList = hm.get("egg");
  for (Paper p : paperList) {
    println(p.title);
  }
}

void draw(){}

class Paper 
{
  //===== variables =====
  int ID;
  int year;
  String title;
  StringList authors  = new StringList();
  StringList keywords = new StringList();
  String DOI;
  String typeOfRef;
  String nameOfSource;
  String abs; // abstract


  //===== constructor =====

  //===== update =====

  //===== display =====
}

3 个答案:

答案 0 :(得分:4)

使用HashMap<String, JournalArticle>数据结构。

例如

Map<String, JournalArticle> journals = new HashMap<String, JournalArticle>();
journals.put("keyword1", testJA);

if (journals.containsKey("keyword1")
{
    return journals.get("keyword1");
}

您可以将关键字作为字符串类型的键放在此地图中,但是,它只支持“完全匹配”类型的搜索,这意味着您必须在您的关键字中使用关键字(存储为Hashmap中的键)搜索范围。

如果您正在寻找“喜欢”类型的搜索,我建议您将对象保存在支持“喜欢”查询的数据库中。

编辑:第二个想法,我认为你可以做一些“喜欢”的查询(就像SQL中的like子句一样),但效率不会太高好的,因为无论何时进行查询,都要遍历HashMap中的所有键。如果您了解正则表达式,则可以通过修改以下示例代码(例如key.matches(pattern))来执行各种查询:

    List<JournalArticle> results = null;

    for (String key : journals.keySet())
    {
        if (key.contains("keyword"))  /* keyword has to be part of the key stored in the HashMap, but does not have to be an exact match any more */
            results.add(journals.get(key));
    }

    return results;

答案 1 :(得分:0)

对于简单的情况,您可以使用Multimap<String, Article>。 Guava图书馆里有一个。

对于大量数据,Apache Lucene将更适合。

答案 2 :(得分:0)

我会创建一个关键字(同样适用于作者或标题等)的地图,也可以创建一组JournalArticles。

Map<String, Set<JournalArticle>> keyWordMap = new HashMap<>();
Map<String, Set<JournalArticle>> authorMap = new HashMap<>();

当您为每个关键词创建一个新的JournalArticle时,您将该文章添加到相应的集合中。

JournalArticle ja = new  JournalArticle();
for(String keyWorld : ja.getKeyWords())
{
    if(keyWordMap.containsKey(keyWorld) == false)
        keyWordMap.put(keyWorld, new HashSet<JournalArticle>());
    keyWordMap.get(keyWorld).add(ja);
}

要查看,请执行以下操作:

String keyWord = "....";
Set<JournalArticle> matchingSet = keyWordMap.get(keyWord);