我有三个清单:
List<String> list1 = new ArrayList<String>();
List<String> list2 = new ArrayList<String>();
List<String> list3 = new ArrayList<String>();
list1.add("return");
list1.add("==");
list1.add("NULL");
list1.add("&&");
list1.add("password");
list2.add("password");
list2.add("&&");
list2.add("return");
list2.add("==");
list2.add("NULL");
list3.add("return");
list3.add("==");
list3.add("NULL");
我想将list1与list2和list3进行比较,如果相似度> = 0.6,则表示它们是相似的列表。在此示例中,list2和list3都是类似的列表。
答案 0 :(得分:0)
您可以使用Java 8 Stream来执行此操作: 使用过滤器可以获得第一个列表和第二个列表或第一个和第三个列表中出现的所有元素。然后,使用计数你可以检查他们的金额。
long same12 = list1.stream()
.filter(s -> list2.contains(s))
.count();
long same13 = list3.stream()
.filter(s -> list1.contains(s))
.count();
System.out.println(((double)same12/(double)list1.size()) >= 0.6 ? "They are similar" : "They aren't similar");
System.out.println(((double)same13/(double)list1.size()) >= 0.6 ? "They are similar" : "They aren't similar");
答案 1 :(得分:0)
当我们拥有良好的旧Java集合集操作时,我认为没有一个很好的理由在这里使用流(除了我们中的一些人喜欢流)。这种方法可以满足您的要求:
public static boolean areSimilar(List<String> list1, List<String> list2) {
List<String> sameElements = new ArrayList<>(list1);
sameElements.retainAll(list2);
double similarity = ((double) sameElements.size()) / list1.size();
return similarity > 0.5999999;
}
我已将threashold设置为略低于0.6,以确保舍入错误不会导致错过3/5的相似性。
根据这种方法,你的三个列表中的任何两个都是相似的。在这些情况下,areSimilar(list1, list2)
和areSimilar(list2, list1)
也会产生true
。
说我介绍
List<String> list4 = Arrays.asList("return", "password");
现在areSimilar(list1, list4)
为false
,但areSimilar(list4, list1)
为真。在某些情况下,参数的顺序很重要,因为您在相似性度量中使用了第一个列表的大小,并且列表的大小不同。但是,areSimilar(list3, list4)
和areSimilar(list4, list3)
都会产生false
,因为这两个列表只有一个共同的元素。