我正在研究两个arraylists来比较两个向量的相似性,一个双数组用于存储相似性值,一个字符串数组用于其索引号。
我用Collections.sort(ArrayList, Collections.reverseOrder())
对双数组进行了排序
降序,但不确定如何使用它对索引号进行排序。
我需要的结果是两个数组按降序排列:
Index ArrayList [2,5,7,9],
余弦相似度ArrayList [0.9,0.7,0.5,0.2],
其中索引号2表示值0.9,索引号5表示值0.7,依此类推。
public void getSimilarity() {
double mySimilarity;
//double mrr1;
List<Double> items1 = new ArrayList<Double>();
List<String> index1 = new ArrayList<String>();
for (int i = 0; i < tfidfDocsVector.size(); i++) {
for (int j = 0; j < tfidfDocsVector.size(); j++) {
int k = j+1;
//cosineSimilarity is defined in another file (now shown here)
mySimilarity = new Similarity().cosineSimilarity
(tfidfDocsVector.get(i),
tfidfDocsVector.get(j));
//store certain vectors only
if (i==9 && k < 10) {
System.out.println("between Query1" + " and " + "string" + k + " = "
+ mySimilarity);
items1.add(mySimilarity);
index1.add(k);
}
}
}
Collections.sort(items1, Collections.reverseOrder());
//how to sort index1 along with items?
System.out.println("Ranked values for query1 - Largest to the smallest " + items1);
答案 0 :(得分:2)
定义一个新的Class,它有两个字段Similarity和Index如下
Class Similarity implements Comparable<Similarity> {
double value;
int index;
public Similarity(double value, int index) {
this.value = value;
this.index = index;
}
@Override
public int compareTo(Similarity that) {
if (this.value > that.value)
return -1;
else if (this.value < that.value)
return 1;
else
return 0;
}
}
您将只拥有上述对象的一个列表,而不是两个列表。
并替换
items1.add(mySimilarity);
index1.add(k);
在您的代码中:
list.add(new Similarity(mySimilarity, k));
最后,只需要Collections.sort(list)
根据Similarity类中定义的比较器函数对列表进行排序。
答案 1 :(得分:1)
这是将两个数组一起排序的一般解决方案。我相信你可以很容易地使它适应ArrayList
而不是数组:
import java.util.*;
public class Sort2Arrays {
public static void main(String[] args) {
// The two arrays we need to sort
String[] strings = {
"E", "D", "H", "B", "F", "A", "G", "C", "I", "J"
};
Double[] doubles = {
7.15, 3.57, 1.54, 5.08, 2.99, 3.65, 4.04, 3.70, 7.07, 0.63
};
// Sort in reverse based on strings
sortTogether(strings, doubles, Collections.reverseOrder());
// Print the results
System.out.println(Arrays.asList(strings));
System.out.println(Arrays.asList(doubles));
}
public static <X,Y> void sortTogether(final X[] xs, final Y[] ys, final Comparator<X> cmp) {
// The arrays must be the same length
assert(xs.length == ys.length);
// First, we create a new array to track the indices
Integer[] indices = new Integer[xs.length];
for (int i=0; i<indices.length; i++) indices[i] = i;
// Second, we create a comparator to sort the indices array
// based on the original array that we want (in this case, xs)
Comparator<Integer> indexCmp = new Comparator<Integer>() {
@Override public int compare(Integer i1, Integer i2) {
return cmp.compare(xs[i1], xs[i2]);
}
};
// Third, we sort the indices with the comparator
Arrays.sort(indices, indexCmp);
// Finally, we re-order the original arrays based on indices
X[] xs0 = Arrays.copyOf(xs, xs.length);
Y[] ys0 = Arrays.copyOf(ys, ys.length);
for (int i=0; i<indices.length; i++) {
xs[i] = xs0[indices[i]];
ys[i] = ys0[indices[i]];
}
}
}
以下是运行上述代码的输出:
$ java Sort2Arrays
[J, I, H, G, F, E, D, C, B, A]
[0.63, 7.07, 1.54, 4.04, 2.99, 7.15, 3.57, 3.7, 5.08, 3.65]
答案 2 :(得分:1)
谢谢大家的回复和提示!我最终使用Hashmap和TreeMap而不是ArrayList。 我能够根据get.Value()按降序对结果进行排名。
public static void printMap(Map<Double, String> map) {
for (@SuppressWarnings("rawtypes") Map.Entry entry : map.entrySet()) {
System.out.println(entry.getValue() + ": " + entry.getKey());
}
}
public void getSimilarity() {
double mySimilarity;
List<Double> items1 = new ArrayList<Double>();
List<String> index1 = new ArrayList<String>();
Map map1 = new HashMap();
for (int i = 0; i < tfidfDocsVector.size(); i++) {
for (int j = 0; j < tfidfDocsVector.size(); j++) {
int k = j+1;
//cosineSimilarity is defined in another file (now shown here)
mySimilarity = new Similarity().cosineSimilarity
(tfidfDocsVector.get(i),
tfidfDocsVector.get(j));
//store certain vectors only
if (i==9 && k < 10) {
System.out.println("between Query1" + " and " + "string" + k + " = "
+ mySimilarity);
map1.put(mySimilarity, k);
}
}
}
Map<Double, String> treeMap1 = new TreeMap(Collections.reverseOrder());
treeMap1.putAll(map1);
System.out.println ("Ranked results similarity measure (most relevant first): ");
printMap(treeMap1);
}
答案 3 :(得分:0)
听起来你想要的是一个对象数组。每个对象都有两个属性,索引和相似性。然后,您可以按相似性进行排序,仍然使用sort()方法,但是传入比较器函数,如此
public static void sort(T [] a, 比较器c)
在这里解释得更多 http://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html