如何按照字符串长度对ArrayList进行排序

3

最近我开始学习计算机科学课程,旨在更好地理解编程,但是在ArrayList实验中遇到了困难。该程序的目的是将x个字符串放入ArrayList中,然后按降序输出结果。

例如:Zebra, Deer, Giraffe Deer

结果:Giraffe,Zebra,Deer

我在网上找到了一些使用ArrayList比较器的示例,但我们的教授希望我们通过过滤最大的单词、打印它、删除它,然后继续循环直到所有单词都被打印出来。

以下是我的代码:

public static void main(String[] args) {

    Scanner input = new Scanner(System.in);
    int length = 0;
    String longest = "";
    String currentWord = "";
    ArrayList <String> DescendArray = new ArrayList<String>();
    System.out.println("What would you like to add to the list?");
    String userInput = input.next();
    while(!userInput.equals("d"))
    {
        DescendArray.add(userInput);
        userInput = input.next();
    }
    for (int i=0; i < DescendArray.size(); i++)
    {
        if (DescendArray.get(i).length() > longest.length())
                {
                    currentWord = DescendArray.get(i);
                    if (currentWord.length() > longest.length())
                    {
                        longest = currentWord;
                        length = longest.length();
                    }
                }
        for (int j=1; j < DescendArray.size() -1 ; j++)
        {
            if (DescendArray.get(j - 1).length() > longest.length())
            {
                DescendArray.remove(j - 1);
            }
            System.out.println(longest + " " + length);
        }
    }
}

我猜测我的错误出现在内部循环中,但无论我使用多少不同的变化,都无法使它正常工作。


“我猜我的错误在内部循环中。” - 这个错误是什么?它没有编译,抛出异常还是给出了错误的结果? - resueman
代码编译正常,这是一个示例输入和输出:输入:长颈鹿,河马,斑马输出:长颈鹿,长颈鹿,长颈鹿 - Nare
需要删除重复的单词吗?在您的示例中,“deer”只出现了一次。 - Julian Rubin
10个回答

3
尝试这个,它对我有效。
     List<String> sorted = list.stream()
                .sorted(Comparator.comparingInt(String::length))
                .collect(Collectors.toList());

但是这个列表不包含相同的字符串吗?似乎问题只想打印一次“Deer”。 - Scratte

3
这基本上是你需要做的事情:
public class Zoo {

    public static void main(String[] args) {
        List<String> zoo = new ArrayList<String>();
        zoo.add("Zebra");
        zoo.add("Deer");
        zoo.add("Giraffe");
        zoo.add("Deer");
        while(!zoo.isEmpty()) {
            String bigger = "";
            for(String animal : zoo) {
                if(animal.length() > bigger.length()) {
                    bigger = animal;
                }
            }
            System.out.println(bigger);
            while(zoo.contains(bigger)) {
                zoo.remove(bigger);
            }
        }
    }

}

根据预期的输出,您应该为每个移除打印动物,每个移除都应该有一次打印。 - James Wierzba
根据他的帖子 -> 结果:长颈鹿,斑马,鹿 - Ulises
@Ulises,不仅抄袭了我的答案,而且使用了基本相同的算法... - KevinO
@KevinO,他的回答比你的早2分钟发布! - James Wierzba
@JamesWierzba,是的,在我的回答出现之前他已经发布了,但我正在编辑器中编写,然后在提交答案后收到了他的通知。不仅是时间问题,而且使用.isEmpty()方法而不是循环对我来说也很有趣。归功于打字速度更快的人。 - KevinO

3
我惊讶于其他解决方案的冗长。一个更简单的方法是使用流(stream):
List<String> original = Arrays.asList("s1", "String 2", "ss3", "s");
List<String> sorted = original.stream()
        .sorted((s1, s2) -> s2.length() - s1.length())
        .collect(Collectors.toList());
System.out.println(sorted);

用你的ArrayList替换“original”。

2
这似乎是有效的。如果你不想删除重复的动物,那么就删除distinct()方法。我省略了列表的创建。
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class Zoo {
    public static void main(String[] args) {
        List<String> zoo = Arrays.asList("Zebra", "Deer", "Giraffe", "Deer");
        String output = zoo.stream()
                           .distinct()
                           .sorted((x, y) -> Integer.compare(y.length(), x.length()))
                           .collect(Collectors.joining(","));
        System.out.println(output);
    }
}

0

我所指的是字符串的长度,因此应按字符串长度从最长到最短排序。 - Nare

0

假设不需要同时删除重复单词,因此重复单词将按顺序被删除,并且列表不需要按字母顺序进行(可以先对列表进行排序),并且线程安全性不重要,我会避免使用整数计数器和检查大小。相反,我会运行输出循环,直到所有内容都被删除。

例如:

public void doRemove()
{
    while (! descendArray.isEmpty()) {
        String longest = "";

        for (String s : descendArray) {
            if (s.length() > longest.length()) {
                longest = s;
            }
        }

        if (longest.length() > 0) {
            if (descendArray.remove(longest)) {
                System.out.println(longest + " (" + longest.length() + ")");
            }
        }
    } // while we stil have things to process
}

0
问题似乎在于,在您的 for 循环的每一次迭代中,您都会发现长颈鹿是您最长的单词,然后您会检查列表的其余部分,以查看它是否比长颈鹿更长。与您现在拥有的不同,我会写出类似这样的内容:
for (int i=0; i < DescendArray.size(); i++)
{
    longest = "";
    length = longest.length();
    int longestIndex = 0;
    for (int j=1; j < DescendArray.size() -1 ; j++)
    {
        currentWord = DescendArray.get(j);
        if (currentWord.length() > longest.length())
        {
            longestIndex = j;
            longest = currentWord;
            length = longest.length();
        }
    }
    DescendArray.remove(longestIndex);
    System.out.println(longest + " " + length);
}

这个嵌套的for循环应该先找到最长的单词,存储索引并在找到下一个最长的单词之前打印和删除该索引处的条目。


0
这里是另一种可以使用的变体,但涉及到一个额外的数组列表:
ArrayList<String> DescendArray = new ArrayList<>();
DescendArray.add("Monkey");
DescendArray.add("Giraffe");
DescendArray.add("Hippo");
DescendArray.add("Zebra");
DescendArray.add("Monkey");

List<String> copy = new ArrayList<>(DescendArray);

for (int i=0; i<DescendArray.size(); i++) {
    String longest = "";
    for (int j=0; j<copy.size(); j++) {
        String current = copy.get(j);
        if (current.length() > longest.length()) {
             longest = current;
        }
    }
    System.out.println(longest);
    while(copy.contains(longest)) {
        copy.remove(longest);
    }        
}

这个完美地运作,并且给了我我需要的确切输出!我的问题是我的for循环做错了,但是添加第二个ArrayList来比较确实有助于找出我的问题所在。非常感谢您的帮助! - Nare
很高兴能帮到你!请记住,这并不是最高效的解决方案,因为它使用了额外的列表。@Ulises提出的建议更加高效。 - hanif

0

当您需要从列表中删除元素时,迭代器是更好的方法。请参见下面的代码。

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

public class Zoo {
    public static void main(String[] args) {
        List<String> zoo = new ArrayList<String>();
        zoo.add("Zebra");
        zoo.add("Deer");
        zoo.add("Giraffe");
        zoo.add("Deer");
        Collections.sort(zoo,new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {          
                return o2.compareTo(o1);
            }
        });
        Iterator<String> iterator=zoo.iterator();
        while (iterator.hasNext()) {
            System.out.println(iterator.next());
            iterator.remove();
        }
    }
}

0

按照字符串长度对ArrayList进行排序,可以尝试以下代码:

private ArrayList SortwithStrlength(ArrayList templist) {
        for(int i=0;i<templist.size();i++)
        {
            for(int j=0;j<templist.size();j++)
            {
                String temp;
                if(templist.get(i).toString().length()<templist.get(j).toString().length())
                {
                    temp=templist.get(i).toString();
                    templist.set(i, templist.get(j).toString());
                    templist.set(j,temp);
                }
            }
        }
        return templist;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接