Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/357.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用google collections对列表进行筛选和排序_Java_Sorting_Filter_Guava - Fatal编程技术网

Java 使用google collections对列表进行筛选和排序

Java 使用google collections对列表进行筛选和排序,java,sorting,filter,guava,Java,Sorting,Filter,Guava,假设我有一个列表(或集合): List testList=Lists.newArrayList(“assocX”、“srcT”、“destA”、“srcX”、“不在乎Y”、“垃圾”、“srcB”); 我想返回一个ImmutableList(集合),它按照自然顺序对术语进行排序/分组,其中以“src”开头的术语排在第一,“assoc”第二,“dest”最后。如果某个术语不包含这些术语,则应将其从结果列表中删除 因此,这里的结果是“srcB”、“srcT”、“assocX”、“destA” 我想我

假设我有一个列表(或集合):

List testList=Lists.newArrayList(“assocX”、“srcT”、“destA”、“srcX”、“不在乎Y”、“垃圾”、“srcB”);
我想返回一个ImmutableList(集合),它按照自然顺序对术语进行排序/分组,其中以“src”开头的术语排在第一,“assoc”第二,“dest”最后。如果某个术语不包含这些术语,则应将其从结果列表中删除

因此,这里的结果是“srcB”、“srcT”、“assocX”、“destA”

我想我可以通过一些Iterables.filter或谓词的组合来实现这一点,但只是看不到而已。我想一定有一种简洁的方法


编辑:一个集合代替一个列表也可以工作。

我认为您必须首先使用谓词来删除您不需要的元素,然后实现一个集合并对列表进行排序。

看一看

Function getNameFunction=新函数(){
公共字符串应用(来自的水果){
从.getName()返回;
}
};
Ordering nameOrdering=Ordering.natural().onResultOf(getNameFunction);
ImmutableSortedSet-sortedFruits=ImmutableSortedSet.orderedBy(
nameOrdering.addAll(fruits.build();

尽管这会返回一个集合。

只要这三个前缀是您唯一关心的事情,我建议如下:

    Predicate<String> filter = new Predicate<String>() {
        @Override
        public boolean apply(String input) {
            return input.startsWith("src") || input.startsWith("assoc") || input.startsWith("dest");
        }
    };

    Function<String, Integer> assignWeights = new Function<String, Integer>() {
        @Override
        public Integer apply(String from) {
            if (from.startsWith("src")) {
                return 0;
            } else if (from.startsWith("assoc")) {
                return 1;
            } else if (from.startsWith("dest")) {
                return 2;
            } else {
                /* Shouldn't be possible but have to do something */
                throw new IllegalArgrumentException(from + " is not a valid argument");
            }
        }
    };

    ImmutableList<String> sortedFiltered = ImmutableList.copyOf(
            Ordering.natural().onResultOf(assignWeights).sortedCopy(
                    Iterables.filter(testList, filter)
            )
    );
谓词过滤器=新谓词(){
@凌驾
公共布尔应用(字符串输入){
返回input.startsWith(“src”)| input.startsWith(“assoc”)| input.startsWith(“dest”);
}
};
函数赋值权重=新函数(){
@凌驾
公共整数应用(字符串来自){
如果(从.startsWith(“src”)){
返回0;
}否则,如果(从.startsWith(“assoc”)){
返回1;
}else if(从.startsWith(“dest”)){
返回2;
}否则{
/*不可能,但必须做点什么*/
抛出新的IllegalArgumentException(from+“不是有效参数”);
}
}
};
ImmutableList sortedFiltered=ImmutableList.copyOf(
Ordering.natural().onResultOf(assignWeights.sortedCopy)(
Iterables.filter(testList,filter)
)
);

如果您开始添加更多的前缀进行筛选或排序,那么此解决方案肯定无法很好地扩展,因为您必须不断更新筛选器和每个前缀的权重。

通常,整理这样明显不同的数据是不好的设计。在您的例子中,当您说“assocX”时,“assoc”与“X”有单独的含义,但您将它们合并在一起

所以我建议设计一个包含两个字段的类。然后,您可以在第一个字段上创建一个排序,在第二个字段上创建另一个排序,并将它们组合起来(例如,ordering#component()。使用将这些字段合并为字符串的toString()方法。作为奖励,这可以通过共享大大减少内存使用


因此,您可以对这些对象的列表进行排序,如果要打印它们,只需对它们调用toString()。

在其他情况下,抛出新的IllegalArgumentException()比
返回3
更好。
Function<Fruit, String> getNameFunction = new Function<Fruit, String>() {
    public String apply(Fruit from) {
        return from.getName();
    }
};

Ordering<Fruit> nameOrdering = Ordering.natural().onResultOf(getNameFunction);

ImmutableSortedSet<Fruit> sortedFruits = ImmutableSortedSet.orderedBy(
    nameOrdering).addAll(fruits).build();
    Predicate<String> filter = new Predicate<String>() {
        @Override
        public boolean apply(String input) {
            return input.startsWith("src") || input.startsWith("assoc") || input.startsWith("dest");
        }
    };

    Function<String, Integer> assignWeights = new Function<String, Integer>() {
        @Override
        public Integer apply(String from) {
            if (from.startsWith("src")) {
                return 0;
            } else if (from.startsWith("assoc")) {
                return 1;
            } else if (from.startsWith("dest")) {
                return 2;
            } else {
                /* Shouldn't be possible but have to do something */
                throw new IllegalArgrumentException(from + " is not a valid argument");
            }
        }
    };

    ImmutableList<String> sortedFiltered = ImmutableList.copyOf(
            Ordering.natural().onResultOf(assignWeights).sortedCopy(
                    Iterables.filter(testList, filter)
            )
    );