【问题标题】:Sorting & Merging Java ArrayList like Python Tuples像 Python 元组一样对 Java ArrayList 进行排序和合并
【发布时间】:2013-04-23 03:50:52
【问题描述】:

我来自 Python 背景,目前正在将我的 Python 程序移植到 Java。我需要有关解决问题的最佳方法的建议。

最初,我在 Python 中创建了一个元组列表:

loft = [('india',1),('accepts',1),('narendra',1), ('modi',1),('manmohan',1),('singh',1),('sonia gandhi',1),('rajkot',1),('sharma',1),('raja',1),('india',2),('manmohan',2),('singh',2),('nepal',2),('prime minister',2),('meeting',2),('economy',2),('manmohan',3),('narendra',3),('modi',3),('gupta',3),('rajkot',3),('patel',3),('singh',3),('rajiv',3),('aajtak',3),('manmohan',4),('nepal',4),('bahadur',4),('king',4),('meeting',4),('economy',4),('wife',4),('plane',4)]

(在印度,accepts 是关键字,数字是从数据库中获取的 id。)。 现在,申请:

di = {}
for x,y in ll:
     di.setdefault(x,[]).append(y)
newdi = {}

我的列表变成了字典:

di = {'manmohan': [1, 2, 3, 4], 'sonia gandhi': [1], 'raja': [1], 'india': [1, 2], 'narendra': [1, 3], 'patel': [3], 'sharma': [1], 'nepal': [2, 4], 'gupta': [3], 'singh': [1, 2, 3], 'meeting': [2, 4], 'economy': [2, 4], 'rajkot': [1, 3], 'prime minister': [2], 'plane': [4], 'bahadur': [4], 'king': [4], 'wife': [4], 'accepts': [1], 'modi': [1, 3], 'aajtak': [3], 'rajiv': [3]}

Java 部分:

    public void step1() throws SQLException{

      Connection con= new Clustering().connect();

      Statement st = con.createStatement();
      Statement st1 = con.createStatement();
      ResultSet rs = st.executeQuery("select uid from url where artorcat=1");

      ArrayList<Tuples> allkeyword = new ArrayList<Tuples>();
      long starttime = System.currentTimeMillis();

      while (rs.next()) {
        int id = rs.getInt("uid");
        String query = "select tags.tagname from tags left join tag_url_relation on tags.tid=tag_url_relation.tid where tag_url_relation.uid="+id;
        ResultSet rs1 = st1.executeQuery(query);
        while (rs1.next()){
          String tag = rs1.getString(1);

          //Creating an object t of type Tuples
          //and pass values to constructor
          Tuples t = new Tuples(id,tag);
          //adding the above tuple to arraylist allkeyword
          allkeyword.add(t);
        }//job done, now lets test by iterating
      }

      Iterator<Tuples> it = allkeyword.iterator();
      while(it.hasNext()){

        Tuples t = it.next();
        System.out.println(t.getId());
        System.out.println(t.getKeyword());
      }

      long endtime = System.currentTimeMillis();
      long totaltime = endtime-starttime;
      System.out.println("Total time:" + totaltime);
    }


And here is Tuples class : 

/**
 * 
 * 
 * Tuple class is created to create a multiple data type tuple. We are using this tuples object to retrieve keyword and 
 * id in step1 in Clustering.java.
 * @author akshayy
 *
 */


public class Tuples {
    int i;
    String s;


    public Tuples(int i, String s) {
        this.i= i;
        this.s=s;
    }


    public int getId(){
        return this.i;
    }

    public String getKeyword(){
        return this.s;      
    }


}

到目前为止一切顺利。我创建了一个包含关键字和 id 的元组类的数组列表。现在如何在 id 中查找关键字的出现的下一步。像 'manmohan' 在 id 1,2,3,4 等中找到。

di = {'manmohan': [1, 2, 3, 4], 'sonia gandhi': [1], 'raja': [1], 'india': [1, 2], 'narendra': [1, 3], 'patel': [3], 'sharma': [1], 'nepal': [2, 4], 'gupta': [3], 'singh': [1, 2, 3], 'meeting': [2, 4], 'economy': [2, 4], 'rajkot': [1, 3], 'prime minister': [2], 'plane': [4], 'bahadur': [4], 'king': [4], 'wife': [4], 'accepts': [1], 'modi': [1, 3], 'aajtak': [3], 'rajiv': [3]}

请建议我在 arraylist 中查找类似项目并像上面那样对它们进行排序的下一个方法。还是我需要完全不同的东西?

【问题讨论】:

    标签: java python arraylist tuples


    【解决方案1】:

    看看 java.lang.Map 接口。您实际上是在构建一个

    Map<String,List<Integer>> 
    

    使用纯 Collections 类,您可以使用 contains 和 Collections.sort 等方法(如果担心性能,可以考虑使用自己的排序算法)

    对于新的 Java 开发人员来说,迭代 Map 并不那么简单,但是您可以迭代 KeySet,在每个迭代点对 map 执行 get 操作,然后对 value 执行 contains,在本例中为一个列表。

    Integer bar = whatever you are evaluating
    Map<String, List<Integer>> fooMap = new HashMap<String, List<Integer>>();
    ... build your map ...
    for(String key:fooMap.keySet()){
        if(fooMap.get(key).contains(bar)){
            ...logic when found...  
        }
    }
    

    【讨论】:

    • 谢谢。一般来说,我需要在 Collections 中查找此类数据结构操作。
    【解决方案2】:

    您需要使用 List 或 Set 值创建地图。根据您的需要,您可以保留 Tuples 类或单独使用 String 和 Integer。

    这是一个例子:

    // construct a map with string key (tag) and list of integers (ids) as the value
    Map<String, List<Integer>> keywords = new HashMap<String, List<Integer>>();
    
    while (rs.next()) {
        int id = rs.getInt("uid");
        String query = "select tags.tagname from tags left join tag_url_relation on tags.tid=tag_url_relation.tid where tag_url_relation.uid="+id;
        ResultSet rs1 = st1.executeQuery(query);
    
        while (rs1.next()){
            String tag = rs1.getString(1);
    
            // construct the List for this keyword
            if (!keywords.containsKey(tag)) {
                keywords.put(tag, new ArrayList<Integer>());
            } 
            keywords.get(tag).add(id);
        }
    }
    

    keywords 将是一个类似于 Python 实现中的数据结构:

    List<Integer> manmohanList = keywords.get("manmohan"); // will get you a list containing the numbers 1,2,3,4
    for (Integer id: manmohanList) {
        System.out.println(id); // prints 1,2,3,4
    }
    

    【讨论】:

    • 谢谢。如果我必须将其应用于大型数据集怎么办。任何性能问题?我想尽可能地使用本地来加快速度。
    • ArrayList 实例的大小随着其中元素的数量而增长。如果没有足够的空间,它将创建另一个大小为原来两倍的后备数组,并且旧后备数组的内容将被复制到新后备数组中。为了优化,您需要为 ArrayList 设置一个好的初始大小,例如:new ArrayList&lt;Integer&gt;(1000000),这样您就可以避免重复和复制。
    • HashMap 以类似的方式工作,但不仅仅是大小,您需要设置大小(表示键的数量)和负载因子。对于大小为 100 且加载因子为 0.75 的 HashMap,当插入第 75 个元素时,其大小会增加。因此,您需要根据您期望的数据量为 HashMap 的大小和负载因子设置适当的值。
    • 对于访问,带String键的HashMap是最快的。
    • 我必须应用一个算法,它的第一步就是这个。关键字的数量越来越多。我有数百万个关键字,需要对它们执行几次操作。似乎这是一个好的开始。如果可以预先确定数量,则 HashMap 对于大型数据集来说已经足够好了。谢谢。
    【解决方案3】:

    与其拥有一个用于元组的类,不如声明一个 HashMap 来存储字典关键字和位置。比如

    Map<String, ArrayList<Integer>> dictionary = new HashMap<String, ArrayList<Integer>>();
    
    //Now before adding any new keyword to the map just check if it contains it or not.
    while (rs1.next()){
       //Your
       //Old
       //Code
       if(dictionary.contains(tag)){
           id_list = dictionary.get(tag);
           id_list.add(id);
           dictionary.put(tag, id_list);
       }else{
            dictionary.put(tag, id);
       }
    }
    

    尚未对其进行拼写错误测试。但我想你应该有一个想法。希望对您有所帮助。

    【讨论】:

    • 我正在构建一个高性能应用程序,需要在大型数据集上每半小时迭代一次。听说HashMap很慢,是吗?
    • 好吧,我从来没有大规模使用过它,但是 get 方法可能会很慢,因为它会遍历一个大地图以找到给定键的特定值(在你的情况下,我担心它可以相对慢)。但是 Java 不是 Python :P 所以对于语言处理你可能不得不妥协。这也是您应该选择的最佳选择。
    • 谢谢。在这种情况下,线程也不适用,以加快速度。
    猜你喜欢
    • 1970-01-01
    • 2021-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-07
    • 2018-04-11
    • 2011-07-07
    • 2018-10-16
    相关资源
    最近更新 更多