使用字符串ArrayList作为参数编写方法

时间:2014-03-28 00:01:50

标签: java methods arraylist

我正在尝试编写一个方法,该方法将String的StringList作为参数,并在每个长度为4的字符串前面放置一个包含四个星号的字符串。

然而,在我的代码中,我在构造方法时遇到错误。

这是我的标记长度类

import java.util.ArrayList;


public class Marklength {

    void marklength4(ArrayList <String> themarklength){
        for(String n : themarklength){
            if(n.length() ==4){
                themarklength.add("****");
            }
        }
        System.out.println(themarklength);
    }

}

以下是我的主要课程:

import java.util.ArrayList;


public class MarklengthTestDrive {
    public static void main(String[] args){

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

        words.add("Kane");
        words.add("Cane");
        words.add("Fame");
        words.add("Dame");
        words.add("Lame");  
        words.add("Same");

        Marklength ish = new Marklength();

        ish.marklength4(words);

    }
}

基本上在这种情况下,它应该运行,因此它会在数组列表的每个前一个元素之前添加一个字符串"****"的arraylist,因为字符串的长度都是4.

BTW

这包括添加其他元素

我不确定我哪里出错了。可能在我的for循环中?

我收到以下错误:

Exception in thread "main" java.util.ConcurrentModificationException
    at java.util.AbstractList$Itr.checkForComodification(AbstractList.java:372)
    at java.util.AbstractList$Itr.next(AbstractList.java:343)
    at Marklength.marklength4(Marklength.java:7)
    at MarklengthTestDrive.main(MarklengthTestDrive.java:18)

非常感谢你。感谢帮助。

6 个答案:

答案 0 :(得分:8)

让我们考虑一下这段代码,假装你没有得到那个例外:

import java.util.ArrayList;


public class Marklength {

    void marklength4(ArrayList <String> themarklength){
        for(String n : themarklength){
            if(n.length() ==4){
                themarklength.add("****");
            }
        }
        System.out.println(themarklength);
    }
}

好的,如果您的列表只包含item,会发生什么。

你点击if(n.length() ==4){行,这是真的,因为你正在查看项目,所以你去执行它的阻止。

接下来,您点击themarklength.add("****");行。您的列表现在在其末尾有元素****

循环继续,您将获得列表中的下一个项目,恰好是您刚刚添加的项目****

您点击的下一行是if(n.length() ==4){。这是真的,所以你执行它的块。 您转到第themarklength.add("****");行,然后将****添加到列表的末尾。

我们在这看到一个糟糕的模式吗?是的,是的,我们这样做。

Java运行时环境也知道这很糟糕,这就是为什么阻止称为并发修改的东西。在您的情况下,这意味着您在迭代时不能修改列表,这就是for循环所做的。

我最好猜测你要做的是这样的事情:

import java.util.ArrayList;


public class Marklength {

    ArrayList<String> marklength4(ArrayList <String> themarklength){
        ArrayList<String> markedStrings = new ArrayList<String>(themarklength.size());
        for(String n : themarklength){
            if(n.length() ==4){
                markedStrings.add("****");
            }
            markedStrings.add(n);
        }
        System.out.println(themarklength);
        return markedStrings;
    }
}

然后:

import java.util.ArrayList;


public class MarklengthTestDrive {
    public static void main(String[] args){

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

        words.add("Kane");
        words.add("Cane");
        words.add("Fame");
        words.add("Dame");
        words.add("Lame");  
        words.add("Same");

        Marklength ish = new Marklength();

        words = ish.marklength4(words);

    }
}

答案 1 :(得分:2)

此...

if(n.length() ==4){
    themarklength.add("****");
}

只是尝试将"****"添加到列表的末尾。这会失败,因为Iterator循环使用的for-each不允许在基础List进行迭代时发生更改。

您可以先创建List的副本......

List<String> values = new ArrayList<String>(themarklength);

或将其转换为String

的数组
String[] values = themarklength.toArray(new String[themarklength.size()]);

并使用这些作为迭代点...

for (String value : values) {

接下来,您需要能够在特定点向ArrayList插入新元素。为此,您需要知道正在使用的值的原始索引...

if (value.length() == 4) {
    int index = themarklength.indexOf(value);

然后在所需位置添加新值...

    themarklength.add(index, "****");

这会在"****"点添加index,推送所有其他条目

<强>更新

正如我所指出的那样,themarklength.indexOf(value)的使用不会考虑themarklength列表包含两个具有相同值的元素的用例,其中会返回错误的索引。

我也没有把性能作为提供可能解决方案的主要要求。

<强>更新...

JohnGarnder和AnthonyAccioly指出,您可以使用for-loop代替for-each,这样可以免除themarklength.indexOf(value)

这将消除重复值搞乱索引位置并提高整体性能的风险,因为您不需要创建第二个迭代器......

// This assumes you're using the ArrayList as the copy...
for (int index = 0; index < themarklength.size(); index++) {
    String value = themarklength.get(index);
    if (value.length() == 4) {
        themarklength.add(index, "****");
        index++;

但你使用的取决于你...

答案 2 :(得分:1)

问题在于,在您的方法中,您没有修改arraylist中的每个字符串,而只是在列表中添加了4个星。所以正确的方法是,你需要修改arraylist的每个元素,并用新的字符串替换旧的字符串:

void marklength4(ArrayList<String> themarklength){
    int index = 0;
    for(String n : themarklength){
        if(n.length() ==4){
            n = "****" + n;
        }
        themarklength.set(index++, n);
    }
    System.out.println(themarklength);
}

如果这不是您想要的,但您想在arraylist中的每个元素之前添加一个新字符串“ * *”,那么您可以在{{listIterator方法中使用ArrayList方法如果长度为4,则在EACH字符串之前添加新的附加元素。

    ListIterator<String> it = themarklength.listIterator();
    while(it.hasNext()) {
        String name = it.next();
        if(name.length() == 4) {
            it.previous();
            it.add("****");
            it.next();
        }
    }

区别在于:ListIterator允许您在迭代时修改列表,并允许您在列表中向后移动。

答案 3 :(得分:1)

我会使用ListIterator代替每个listiterator.addWorking example可能完全按照您的意愿行事。

public void marklength4(List<String> themarklength){
    final ListIterator<String> lit = 
        themarklength.listIterator(themarklength.size());
    boolean shouldInsert = false;   
    while(lit.hasPrevious()) {
        if (shouldInsert) {
            lit.add("****");
            lit.previous();
            shouldInsert = false;
        }
        final String n = lit.previous();
        shouldInsert = (n.length() == 4);
    }
    if (shouldInsert) {
        lit.add("****");
    }
}

{{3}}

答案 4 :(得分:0)

哦,我记得过去美好时代的这个错误。问题是,在访问数组元素时,ArrayList并未完全填充。想一想,你创建了对象然后立即开始循环它。因此,当循环将要运行时,对象必须填充值。

解决此问题的简单方法是预先填充ArrayList。

public class MarklengthTestDrive {
    public static void main(String[] args){

        ArrayList <String> words = new ArrayList<String>() {{ 

        words.add("Kane");
        words.add("Cane");
        words.add("Fame");
        words.add("Dame");
        words.add("Lame");  
        words.add("Same");
        }};
    }
}

请告诉我是否修复了它。您还可以使用static初始化程序。

答案 5 :(得分:0)

制作临时arraylist,修改此列表并将其内容最后复制到原始列表

    import java.util.ArrayList;

    public class MarkLength {
    void marklength4(ArrayList <String> themarklength){
        ArrayList<String> temp = new ArrayList<String>();
        for(String n : themarklength){
            if(n.length() ==4){
                temp.add(n);
                temp.add("****");
            }
        }
        themarklength.clear();
        themarklength.addAll(temp);
        System.out.println(themarklength);
    }
}