从Set in Java中筛选出项目

时间:2012-05-23 16:23:07

标签: java

我有一个项目列表(即字符串),我需要对其进行排序/过滤。

最终结果应包含任何重复(简单),我会将它们全部放入Set中。所以我现在有一套字符串。

更多解释..

我还有一个方法x来计算两个字符串之间的差异量(使用levenstein距离)。

问题:

在将新字符串string插入我的集set之前,我想使用x和其他任何方法之间的方法string检查 levenstein距离 set中的字符串以及如果x返回>=3而不是我不应该添加它。

我最好的做法是什么?除了要插入的每个set的迭代槽string之外?

3 个答案:

答案 0 :(得分:2)

通过Set进行迭代将是您最好的选择,因为没有任何内置的Set实现可以帮助您缩小可能性。

答案 1 :(得分:2)

我玩过如何做到这一点的想法。没有任何迭代次数,我想不出办法做到这一点。

假设您有一个名为distance(String,String):int的方法,它返回两个字符串之间的给定距离。

String x = "Obi-wan"; //this is the item subject to eval addition
List<String> items = new ArrayList<String>(asList("Luke","Yoda","Anakin"));
if (items.filter(s -> distance(s, x) >= 3).getFirst() == null) {
  items.add(x);
}

如果您使用JDK8 Preview,则可以使用上述代码立即执行此操作。 Iterables.getFirst()方法不会迭代整个集合,只会在找到满足条件的第一个元素之前。

否则,您可能必须实现Predicate接口和过滤方法。

interface Predicate<T> {
    public boolean eval(T o);
}

public static void main(String[] args) {
   final String x = "Obi-wan"; //this is the item subject to eval addition
   List<String> items = new ArrayList<String>(asList("Luke","Yoda","Anakin"));
   Predicate<String> p = new Predicate<String>() {
       public boolean eval(String s){ 
           return distance(s, x) >= 3;
       }
   };
   if(filter(items, p).isEmpty()){ 
        items.add(x);
   }
}

public static <T> List<T> filter(List<? extends T> items, Predicate<? super T> predicate){
    List<T> destiny = new ArrayList<T>();
    for(T item : items){
       if(predicate.eval(item){
           destiny.add(item);
       }
    }
    return destiny;
}

或者,您可以在找到满足条件的第一项后停止过滤。

答案 2 :(得分:1)

创建集合时可以使用自定义比较器。在比较器中,如果它们相同(根据常规字符串比较规则)或者它们的Levenstein距离符合您的标准,则返回两个字符串相同。

当您的comaprator说两个字符串相同时,新字符串不会插入到集合中。 (注意,这意味着字符串的最终结果可能取决于插入的顺序)

更新:处理有关总排序的评论:

使用上述建议的比较器会使得结果依赖于插入顺序(如上所述),因为使用的Levenstein距离标准没有定义总排序,因此任何其他解决方案都是如此。

OTOH,一旦一个字符串通过了不相等的测试并被插入到集合中,集合中的其他字符串将不会比较此字符串,因此集合中的字符串将使用它们的自然字符串排序,这确实定义了总排序,因此在集合的内部操作(例如排序)中不会出现进一步的不一致。