从Arraylist中提取不同字符串的更快方法

时间:2015-04-13 13:42:25

标签: java string arraylist java-8 distinct-values

我有一个Dico的ArrayList,我尝试从Dico的Arraylist中提取一个不同的字符串。

这是Dico课程。

public class Dico implements Comparable {
private final String m_term;
private double m_weight;
private final int m_Id_doc;

public Dico(int Id_Doc, String Term, double tf_ief) {
    this.m_Id_doc = Id_Doc;
    this.m_term = Term;
    this.m_weight = tf_ief;
}

public String getTerm() {
    return this.m_term;
}

public double getWeight() {
    return this.m_weight;
}

public void setWeight(double weight) {
    this.m_weight = weight;
}

public int getDocId() {
    return this.m_Id_doc;
}
}

我使用此函数从此数组的中间提取1000个不同的值: 我从中间开始,我只在左右两个方向上采取不同的值

public static List <String> get_sinificativ_term(List<Dico> dico)
 {
   List <String> term =  new ArrayList();
   int  pos_median= ( dico.size() / 2 );
   int count=0;
   int i=0;
   int j=0;   
  String temp_d = dico.get(pos_median).getTerm();
  String temp_g =temp_d;
  term.add(temp_d);

 while(count < 999) // count of element 
  {   
   if(!temp_d.equals(dico.get( ( pos_median + i) ).getTerm()))

 {    
     temp_d = dico.get(( pos_median + i)).getTerm(); // save current term in temp
     //  System.out.println(temp_d);
       term.add(temp_d);  // add term to list                            
       i++;     // go to the next value-->right
       count++;
     //  System.out.println(temp_d);
   }

  else
       i++; // go to the next value-->right

  if(!temp_g.equals(dico.get( ( pos_median+j ) ).getTerm()))

 {    
       temp_g = dico.get(( pos_median+j )).getTerm();

      term.add(temp_g );// add term to array
     //  System.out.println(temp_g);
      j--; //  go to the next value-->left

      count++;
   }
  else 
         j--;//  go to the next value-->left

}      
    return term;
 }

我想让我的解决方案比这个函数更快,如果有可能,我可以用Java SE 8 Streams做到这一点吗?

2 个答案:

答案 0 :(得分:1)

Streams不会让它更快,但可以使它更简单,更清晰。

这是最简单的版本。它将获取所有列表索引,按距离排列到列表中间,获取相应的术语,过滤掉重复项并限制为1000个元素。它肯定比你的迭代代码慢,但更容易理解,因为代码整齐地反映了它的英文描述:

public static List<String> get_sinificativ_term(List<Dico> dicolist) {
    int size = dicolist.size();

    return IntStream.range(0, size)
            .boxed()
            .sorted(comparing(i -> Math.abs(size / 2 - i)))
            .map(dicolist::get)
            .map(Dico::getTerm)
            .distinct()
            .limit(1000)
            .collect(toList());
}

如果您的列表非常庞大并且您希望避免对其进行排序,那么您可以通过一些简单性来换取性能。这个版本做了一些数学运算从中心左右 - 左:

public static List<String> get_sinificativ_term(List<Dico> dicolist) {
    int size = dicolist.size();

    return IntStream.range(0, size)
            .map(i -> i % 2 == 0 ? (size + i) / 2 : (size - i - 1) / 2)
            .mapToObj(i -> dicolist.get(i).getTerm())
            .distinct()
            .limit(1000)
            .collect(toList());
}

答案 1 :(得分:0)

你不能做这样的事吗?

public static List <String> get_sinificativ_term(List<Dico> dico) {
    List<String> list = dico.stream()
                            .map(Dico::getTerm)
                            .distinct()
                            .limit(1000)
                            .collect(Collectors.toList());
    if(list.size() != 1000) {
         throw new IllegalStateException("Need at least 1000 distinct values");
    }
    return list;
}

您需要检查大小,因为您可以使用少于1000个不同的值。如果效率是一个问题,您可以尝试并行运行管道并测量它是否更快。