Java,排序双精度数组及其索引

时间:2017-02-15 11:23:34

标签: java arrays sorting arraylist

我在这个论坛和其他论坛上已经阅读了很多相关内容,但我仍然无法得到具体的答案。无论如何,我决定这样做:

这是一个保存字符串和整数的类:

public class Tuple{

    private String token;
    private int docID;



    public Tuple(String token, int docID) {
        this.token = token;
        this.docID = docID;
    }

    public String getToken() {
        return token;
    }
    public void setToken(String token) {
        this.token = token;
    }
    public int getDocID() {
        return docID;
    }
    public void setDocID(int docID) {
        this.docID = docID;
    }

}

然后,我创建一个数组列表来放置这些元组private ArrayList<Tuple> temps = new ArrayList<>();

然后我像这样填充arraylist:

for ( int i = 0; i < numberOfDocs; i++ )
{
    Tuple cat = new Tuple(Double.toString(vect[i]),i);
    temps.add(cat);
}

最终,我正在对数组进行排序:

public void sortTmp() 
{
    Collections.sort(temps, new Comparator<Tuple>() 
    {
        @Override
        public int compare(Tuple tr2, Tuple tr1)
        {
            return tr2.getToken().compareTo(tr1.getToken());
        }
    });
}

java和double有一些问题,我不能直接使用我的双矩阵,所以我必须做Double.toString()。结果是排序的,但并不完全正确,因为双倍的字符串计算在双数排序方面不是很准确。

有什么想法吗?

5 个答案:

答案 0 :(得分:4)

如果您按字典顺序比较String,通过他们的Tuple表示,您可能确实会发现一些意想不到的结果。

你可以:

  • 重构token,以便doubleDouble(或包装compareTo,如果您想在实例上调用Comparator
  • 否则,在您的Double.parseDouble中,您可以在String上调用String(这应该相对安全,因为double来自compareTo Double首先是s),并在返回的Double包装器上调用String

最后一个选项听起来很难看,因为compareTo和{{1}}之间有一堆看似不必要的来回转换,反之亦然。

这也意味着性能下降,因为在对集合进行排序时会多次调用{{1}}。

答案 1 :(得分:3)

您可以在Tuple中将标记存储为double,并实现Comparable界面。在getToken中,您可以返回实际需要的双重字符串表示形式。

public class Tuple implements Comparable<Tuple>{

    private double token;
    private int docID;

    public Tuple(double token, int docID) {
        this.token = token;
        this.docID = docID;

    }

    public String getToken() {
        return String.valueOf(token);
    }
    public void setToken(double token) {
        this.token = token;
    }
    public int getDocID() {
        return docID;
    }
    public void setDocID(int docID) {
        this.docID = docID;
    }

    @Override
    public int compareTo(Tuple o) {
        return Double.compare(this.token, o.token);
    }
}

答案 2 :(得分:0)

如果你真的需要将双打转换成字符串,那么使用它会更安全

BigDecimal.valueOf(vect[i])).toString(); 

因为它处理双重不可预测性。

答案 3 :(得分:0)

我和Vlad Bochenin有同样的想法:

您只需实施Comparable并覆盖compareTo

public class Tuple implements Comparable<Tuple> {

    public Double token;
    public int docID;

    public Tuple(final double token, final int docID) {
        this.token = token;
        this.docID = docID;
    }

    @Override
    public int compareTo(final Tuple o) {
        return this.token.compareTo(o.token);
    }
}

单元测试:

public class TestTuple {

    @Test
    public void testSort() {
        final Random r = new Random(System.currentTimeMillis());
        final int numberOfDocs = 100;
        final ArrayList<Tuple> temp = new ArrayList<Tuple>();
        for (int i = 0; i < numberOfDocs; i++) {
            temp.add(new Tuple(r.nextDouble(), i));
        }
        Collections.sort(temp);

        Tuple old = temp.get(0);
        // test if sorted
        for (final Tuple next : temp) {
            Assert.assertTrue(next.token >= old.token);
            old = next;
        }
    }
}

答案 4 :(得分:-1)

您可以在您的元组中将标记存储为double并实现Comparable接口。在getToken中,您可以返回实际需要的双重字符串表示形式。

private double token;
private int docID;

public Tuple(double token, int docID) {
    this.token = token;
    this.docID = docID;

}

public String getToken() {
    return String.valueOf(token);
}
public void setToken(double token) {
    this.token = token;
}
public int getDocID() {
    return docID;
}
public void setDocID(int docID) {
    this.docID = docID;
}

@Override
public int compareTo(Tuple o) {
    return Double.compare(this.token, o.token);
}

}

To see More about CompareTo