在arraylist中重新排列对象

时间:2014-02-09 16:04:54

标签: java sorting arraylist

public void go()
{
    ArrayList<String> fruits = new ArrayList<>();

    fruits.add("pear");
    fruits.add("pineapple");
    fruits.add("oranges");
    fruits.add("banana");
    fruits.add("apple");

    for(String str: fruits)
    {
         if(str.contains("apple"))
         {   /* I would like anything containing 'apple' 
          * i.e. apple & pineapple to be placed on top of the array*/   }
    }
    for(String str: fruits)
    {
        System.out.println(str);
    }
}

如您所见,上面的代码如果正常打印,将导致

梨,菠萝,橘子,香蕉,苹果。

我怎样才能对这个数组进行排序,就像苹果的任何东西首先按字母顺序排序一样,那些不是的东西应该保持不变。即,输出应如下所示:

苹果,菠萝,梨,橘子,香蕉。

是否有可能绕过它?

4 个答案:

答案 0 :(得分:4)

我会将列表拆分为两个:包含apple的项目和不包含List<String> apples = new ArrayList<>(); List<String> nonApples = new ArrayList<>(); for (String fruit : fruits) { if (fruit.contains("apple")) { apples.add(fruit); } else { nonApples.add(fruit); } } Collections.sort(apples); apples.addAll(nonApples); // apples now contains what you want. Of course, it's now misnamed :) 的项目。然后对包含苹果的列表进行排序,然后附加不包含苹果的列表。

List<String> result = new ArrayList<>(apples);
Collections.sort(result);
result.addAll(nonApples);

作为最后几行的替代方案,创建仅限苹果列表的副本:

for (int i = 0; i < result.size(); i++) {
  fruits.set(i, result.get(i));
}

这几乎与JB Nizet的方法相同,只是每个项目只检查一次apple-containment,而不是两次检查原始列表。除非您的真实支票非常昂贵,否则这不太可能成为性能瓶颈,因此请使用您喜欢的方法。

目前尚不清楚您是否需要将结果放在原始列表中,或者是否可以使用结果创建新列表。

如果您需要将它们放在原始列表中,您可以随时使用:

Collections.sort

使用{{1}}依赖它稳定的方法很有意思 - 但我个人觉得它们不如这种方法清晰。

答案 1 :(得分:2)

比较者不是正确的答案。我就是这样做的:

List<String> containingApple = new ArrayList<>();
for (String s : list) {
    if (s.contains("apple")) {
        containingApple.add(s);
    }
}
Collections.sort(containingApple);
List<String> result = new ArrayList<>(list.size());
result.addAll(containingApple);
for (String s : list) {
    if (!s.contains("apple")) {
        result.add(s);
    }
}

答案 2 :(得分:2)

您还可以将Collections.sort()方法与自定义一次性比较器一起使用,如下所示:

Collections.sort(fruits, new Comparator<String>(){

        @Override
        public int compare(String arg0, String arg1) {
            if (arg0.contains("apple") && arg1.contains("apple")) {
                return arg0.compareTo(arg1);
            }
            else if (arg0.contains("apple") && !arg1.contains("apple")){
                return -1;
            }
            else if (!arg0.contains("apple") && arg1.contains("apple")){
                return 1;
            } else return 0;
        } });

请注意,else return 0的最终声明至关重要,以确保不会对不包含“apple”的其他值进行排序。

答案 3 :(得分:2)

这是一段非常丑陋的代码,但它可以解决这个问题 我们的想法是以一种方式实现Comparator,如果两个字符串都包含apple,则按字典顺序进行比较,如果只有其中一个字符串进行比较,则认为它“更小”,如果两者都不存在,则视为“相等”(即,我们返回0,不要改变顺序)。

public class AppleStringComparator implements Comparator<String> {

    @Override
    public int compare(String o1, String o2) {
        if (o1.contains("apple")) {
            if (o2.contains("apple")) {
                return o1.compareTo(o2);
            } else {
                return -1;
            }
        } else {
            if (o2.contains("apple")) {
                return 1;
            } else {
                return 0;
            }
        }
    }
}

public class MainClass {
    public void go() {
        // The example code from the OP
        ArrayList<String> fruits = new ArrayList<>();

        fruits.add("pear");
        fruits.add("pineapple");
        fruits.add("oranges");
        fruits.add("banana");
        fruits.add("apple");

        Collections.sort(fruits, new AppleStringComparator());

        // Print out the result, for completeness' sake:
        System.out.println(fruits);
}