ArrayList的顺序相反

时间:2016-10-18 20:44:44

标签: java arraylist

我需要从第一个元素参数的第一个出现开始,然后以第二个参数的下一个出现结束,将它们按相反的顺序排列。

即:

ArrayList<String> food

tomato cheese chips fruit pie butter tea buns

,这两个参数是chipsbuns

新的ArrayList应为

buns tea butter pie fruit chips

这就是我所拥有的,但是当打印时,arraylist是空的

public static void main (String[] args){

       ArrayList<String> food = new ArrayList<String>(); 
       food.add(new String("tomato")); 
       food.add(new String("cheese")); 
       food.add(new String("chips")); 
       food.add(new String("fruit"));
       food.add(new String("pie"));
       food.add(new String("butter"));
       food.add(new String("tea"));
       food.add(new String("buns"));

       ArrayList<String> f1 = reverseOrder(food,"chips","buns");

    }

    public static ArrayList<String> reverseOrder(ArrayList<String> a, String w1, String w2){

        ArrayList<String> food = new ArrayList<String>();

        int startingPos = 0;
        int endingPos = 0;

        boolean startAdding = false;

        for(int i=0; i<a.size(); i++){
            String n = a.get(i);

            if(n.equals(w1)){
                endingPos = i;
            }

            if(n.equals(w2)){
                startingPos = i;
            }

        }


        for(int j = startingPos; j<=endingPos; j--){
            String p = a.get(j);
            food.add(p);
        }


        System.out.print(food);

        return food;
    }

4 个答案:

答案 0 :(得分:2)

你要解决的问题实际上是两个问题。首先,您需要确定您关心的范围(指数)。然后执行相反的操作。

你有第一部分。第二部分可以通过重复删除和插入值来完成,但我建议改为交换。

ArrayList l; 
int begin, end;
//reverse everything from "begin" to "end".
while(begin<end){
    Object tmp = l.get(begin);
    l.set(begin, l.get(end));
    l.set(end, tmp);
    begin++;end--;
}

您还应该知道Java Collections已经为您提供了简单的方法来反转列表。

Collections.reverse(list);

另外,如果您需要不同的列表而不像原来那样修改原始列表,您可以获取这样的子列表。

list.subList(fromIndex, toIndex)

通过这种方式,您可以结合上述内容轻松完成任务。

答案 1 :(得分:1)

您可以使用indexOflastIndexOf来获取元素的正确位置。

如果找不到元素,那些方法将返回-1,所以请注意这一点。

public static void main(String[] args) throws Exception {
    List<String> food = Arrays.asList("tomato", "cheese", "chips", "fruit", "pie", "butter", "tea", "buns");

    ArrayList<String> lst = reverseOrder(food, "chips", "buns");
    System.out.println(lst);
}

private static ArrayList<String> reverseOrder(List<String> food, String start, String end) throws Exception {
    int startIndex = food.indexOf(start);
    if (startIndex < 0) {
        throw new Exception(start + " not found");
    }

    int endIndex = food.lastIndexOf(end);
    if (endIndex < 0) {
        throw new Exception(end + " not found");
    }

    ArrayList<String> lst = new ArrayList<>();
    while (endIndex >= startIndex) {
        lst.add(food.get(endIndex--));
    }
    return lst;
}

输出[buns, tea, butter, pie, fruit, chips]

答案 2 :(得分:1)

这段代码错了:

for(int j = startingPos; j<=endingPos; j--){
    String p = a.get(j);
    food.add(p);
}

为什么呢?一些例子:

  • 想象一下,你传递了这些参数(&#34;番茄&#34;,&#34;奶酪&#34;)=&gt;起始位置将为1,结束位置将为0.在循环验证中,您有&#34;从j = 1开始执行循环,而j <= 0&#34;这意味着它永远不会进入周期

  • 想象一下,你传递了这些参数(&#34; cheese&#34;,&#34; tomato&#34;)=&gt;起始位置将为0,结束位置将为1.在循环验证中,您有&#34;从j = 0开始执行循环,而j <= 1,并且在每次迭代中将1减少到j&#34;意思是在第一次迭代后j = -1并且你将有一个超出范围的索引异常

以下是基于您的代码(为了您更好的理解),它会为您提供所需的结果:

      //this code is case sensitive
      public ArrayList<String> reverseOrder(ArrayList<String> food, String w1, String w2) {
        String startingEl = null;
        String endingEl = null;

        for(int i=0; i<food.size(); i++){
            String n = food.get(i);

            //verify if it's equal and if it's really the first occurrence
            if(n.equals(w1) && endingEl==null){
                endingEl = n;
            }

            //verify if it's equal and if it's really the first occurrence
            if(n.equals(w2) && startingEl==null){
                startingEl = n;
            }

            //if both are found, save some time by interrupting the loop
            if(startingEl!=null && endingEl!=null) break;
        }

        //Protect here your code in case of the first or last elements is not found

        ArrayList<String> food_reversed = new ArrayList<String>();
        food_reversed.add(0, startingEl);

        for(int j = (food.size()-1); j>=0; j--){
            String p = food.get(j);
            if(p==startingEl || p==endingEl) continue;
            food_reversed.add(p);
        }

        food_reversed.add(endingEl);


        System.out.println(food_reversed);

        return food_reversed;
    }

如果我理解正确的挑战,这里有一个不同的代码示例来解决您的问题:

    //this code is case sensitive, is not prepared for repeated string elements
    //and is not prepared if both arguments are exactly the same string
    //is not prepared in cases that the any of the string arguments doesn't exist in the food array
    //this code doesn't insert the same element reference on first and last element
    //This code is not the perfect solution cause as you see it has a lot of ails, but it's probably a good start for your to learn more about the subject
    import java.util.ArrayList;
    import java.util.Collections;

    public class QuestionOrderChallenge {
        ArrayList<String> food = new ArrayList<String>(); 

        public QuestionOrderChallenge() {
            food.add(new String("tomato")); 
            food.add(new String("cheese")); 
            food.add(new String("chips")); 
            food.add(new String("fruit"));
            food.add(new String("pie"));
            food.add(new String("butter"));
            food.add(new String("tea"));
            food.add(new String("buns"));

            ArrayList<String> a1 = reverseOrder(food,"chips","buns");
            ArrayList<String> a2 = reverseOrder(food,"pie","tea");
            ArrayList<String> a3 = reverseOrder(food,"tomato","cheese");

        }

        public ArrayList<String> reverseOrder(ArrayList<String> food, String last, String first) {
            ArrayList<String> reversed_food = new ArrayList<String>(food);
            reversed_food.remove(first);
            reversed_food.remove(last);
            Collections.reverse(reversed_food);
            reversed_food.add(0, first);
            reversed_food.add(last);

            System.out.println("Array ordered according to challenge: " + reversed_food);

            return reversed_food;
        }

        public static void main(String[] args) {
            new QuestionOrderChallenge();
        }

    }

如果您希望获得相同的基本挑战,然后按字母顺序排序,请输入以下代码:

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

public class AlphabeticOrderChallenge {
    ArrayList<String> food = new ArrayList<String>(); 

    public AlphabeticOrderChallenge() {
        food.add(new String("tomato")); 
        food.add(new String("cheese")); 
        food.add(new String("chips")); 
        food.add(new String("fruit"));
        food.add(new String("pie"));
        food.add(new String("butter"));
        food.add(new String("tea"));
        food.add(new String("buns"));

        ArrayList<String> f1 = reverseOrder(food,"chips","buns");
        System.out.println("Array ordered according to challenge: " + f1);
    }

    public ArrayList<String> reverseOrder(ArrayList<String> food, String end, String begin) {
        Collections.sort(food, new ComparatorChallenge(end, begin));
        return food;
    }


    private class ComparatorChallenge implements Comparator {
        String endarg;
        String beginarg;

        public ComparatorChallenge(String beginarg, String endarg) {
            this.beginarg = beginarg.toUpperCase();
            this.endarg = endarg.toUpperCase();
        }

        @Override
        public int compare(Object arg0, Object arg1) {
            String a = ((String)arg0).toUpperCase();
            String b = ((String)arg1).toUpperCase();

            if(a.compareTo(endarg)==0 || b.compareTo(beginarg)==0) return -1;
            if(b.compareTo(endarg)==0 || a.compareTo(beginarg)==0) return 1;

            return b.compareTo(a);
        }
    }


    public static void main(String[] args) {
        new AlphabeticOrderChallenge();
    }

}

答案 3 :(得分:0)

问题分为两部分。首先,我们需要找到满足条件的子列表。获得子列表后,我们可以使用Collections.reverse(List<?> list)来反转它。

首先,找到两个元素之间的子列表,包括在内。主要思想是使用indexOf确定这两个元素的索引,然后在其上调用subList。但我们需要记住,指数可能与我们想象的顺序不同。

private static <T> List<T> inclusiveSublist(List<T> src, T from, T to) {
    int start = src.indexOf(from), stop = src.indexOf(to);

    if (start != -1 && stop != -1) {
        // Successfully located both! But they could be in the "wrong" order
        if (start <= stop) 
             // Element from could appear before to in the list (Plus one to include the second element)
            return src.subList(start, 1 + stop);
        else // Or the other way around
            return src.sublist(stop, 1 + start);
    }

    // Return empty list if we cannot find both elements
    return Collections.emptyList();
}

现在我们只需要反转inclusiveSublist

的结果
public static <T> List<T> inclusiveReverseSublist(List<T> src, T from, T to) {
    List<T> l = inclusiveSublist(src, from, to);
    Collections.reverse(l);
    return l;
}

测试:

public static void main(String [] args) {
    List<String> src = new ArrayList<>();
    src.addAll(Arrays.asList("tomato cheese chips fruit pie butter tea buns".split("\\s")));
    System.out.println(src);
    System.out.println(inclusiveReverseSublist(src, "fruit", "buns"));
    System.out.println(inclusiveReverseSublist(src, "cheese", "tomato"));
}

关于subList()

来自Java API文档subList

  

返回指定fromIndex(包含)和toIndex(独占)之间此列表部分的视图。 (如果fromIndex和toIndex相等,则返回的列表为空。)返回的列表由此列表支持,因此返回列表中的非结构更改将反映在此列表中,反之亦然。返回的列表支持此列表支持的所有可选列表操作。

因此,上面的代码实际上会修改原始列表,将System.out.println(src);移到底部会确认这一点。