【问题标题】:Sorting an ArrayList<String> by order of creation [Android/Java]按创建顺序对 ArrayList<String> 进行排序 [Android/Java]
【发布时间】:2019-02-20 06:28:34
【问题描述】:

所以我正在开发一个应用程序,并且我有一个按钮,用户单击该按钮可以循环浏览数组列表的三个排序集。我有它 Collections.sort(list) 按数字和字母顺序对列表进行排序,但我试图使其 list索引号添加时间排序。

这是我所拥有的:

public class MainActivity extends Activity 
{
    ArrayList<String> list;
    ArrayAdapter adapter;
    ListView listView;
    public int counter;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        list = new ArrayList<>();
        listView = findViewById(R.id.listView);
        adapter = new ArrayAdapter<String>(MainActivity.this,android.R.layout.simple_list_item_1,list);
        listView.setAdapter(adapter);
        addEntries();

        listView.setOnItemClickListener(new AdapterView.OnItemClickListener(){

                @Override
                public void onItemClick(AdapterView<?> p1, View p2, int p3, long p4)
                {

                }
        });
    }

    public void addEntries(){
        for(int e=0; e<=10; e++){
            list.add(String.valueOf(e));
        }
        adapter.notifyDataSetChanged();
    }

    public void sort(View v){
        counter = counter + 1;
        if(counter == 2){
            counter = 0;
        }
        switch(counter){
            case 0:Collections.sort(list);
            message("0");
            break;

            case 1://code to sort by time/index;
            message("1");
            break;

        }
        adapter.notifyDataSetChanged();
    }

    public void message(String message){
        Toast.makeText(getApplicationContext(),message,Toast.LENGTH_SHORT).show();
    }
}

【问题讨论】:

    标签: java android string sorting arraylist


    【解决方案1】:

    最新答案

    最好在列表中存储一个对象而不是字符串。

    class Info {
      String value;
      Long time;
      int index;
    }
    
    new ArrayList<Info>()
    

    添加项目后,更新时间戳,并将索引设置为列表长度。

    然后按字段排序

    list.sort((a,b)-> a.time - b.time )
    list.sort((a,b)-> a.value.compareTo(b.value) )
    list.sort((a,b)-> a.index - b.index )
    

    您可以使用map 函数轻松获取原始字符串列表。

    list.map(it->it.value)
    

    其他问题

    • 添加项目时需要重新排序。

    • 上面的 lambda 有快捷表示法。


    旧答案

    否则您需要从其他地方(地图等)获取时间:

    list.sort((a,b)-> getTimeFromSomewhere(a) - getTimeFromSomewhere(b) )
    

    你真的应该复制一份,这样在按索引排序时你仍然有原来的基于索引的列表:

    new ArrayList<String>(list).sort((a,b)-> getTimeFromSomewhere(a) - getTimeFromSomewhere(b) )
    

    要按索引排序,请返回原始列表的副本。

    new ArrayList<String>(list)
    

    要按字母顺序排序,请使用默认排序返回原始列表的副本

    new ArrayList<String>(list).sort()
    

    【讨论】:

    • 如果列表是用户创建的,这仍然有效吗?我希望它最终达到用户可以输入多个条目并能够通过按下按钮对其进行排序的程度。如果用户能够在不同时间输入条目,我认为永远不会有“原始列表”,不是吗?
    • 当用户在原始列表中添加另一个项目时,您将再次调用排序。您需要原始列表的唯一原因是记住索引顺序。拥有一个包含字符串值、时间戳和索引的对象列表会更有意义。使用我的第一个示例根据每个对象字段进行排序。
    • @CouchMango 我用建议的设计更改更新了答案。
    • 我会试试这些并回复你
    • 好吧,这对我来说没有意义。你是什​​么意思复制列表?有没有办法简单地按索引对数组列表中的字符串进行排序?我不应该说时间,因为我希望条目按添加到 Arraylist 的顺序排列。
    【解决方案2】:
        ArrayList<String> list = new ArrayList<>();
        for (int e = 0; e <= 10; e++) {
            list.add(String.valueOf(e));
        }
    
        Collections.sort(list);
        System.out.println("Sorted as strings:  " + list);
    
        Collections.sort(list, Comparator.comparingInt(Integer::parseInt));
        System.out.println("Sorted numerically: " + list);
    

    输出:

    Sorted as strings:  [0, 1, 10, 2, 3, 4, 5, 6, 7, 8, 9]
    Sorted numerically: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    

    Comparator.comparingInt 是 Java 8 中的新功能,可能仅适用于较新的 Android 版本。 Java 7 等价物更冗长,但确实存在。您的搜索引擎可以提供帮助。

    一个更镀金的解决方案:设计一个模型类并制作该类的实例列表,而不是字符串列表。让您的班级包含 Instant 创建时间,以便您可以按它排序。

    你能举个例子吗?

    编辑:这是一个模型类的简单示例。您更清楚自己的条目是什么以及条目中需要包含哪些内容。

    public class Entry {
    
        String name;
        final Instant created = Instant.now();
    
        public Entry(String name) {
            this.name = name;
        }
    
        public String getName() {
            return name;
        }
    
        public Instant getCreated() {
            return created;
        }
    
        @Override
        public String toString() {
            return name;
        }
    
    }
    

    将此类的实例放入列表并对其进行排序:

            ArrayList<Entry> list = new ArrayList<>();
            for (int e = 0; e <= 10; e++) {
                list.add(new Entry(String.valueOf(e)));
            }
    
            Collections.sort(list, Comparator.comparing(Entry::getName));
            System.out.println("Sorted by name:          " + list);
    
            Collections.sort(list, Comparator.comparing(Entry::getCreated));
            System.out.println("Sorted by creation time: " + list);
    

    由于模型类的toString方法只是打印了名称(不是创建时间),所以输出和之前很相似:

    Sorted by name:          [0, 1, 10, 2, 3, 4, 5, 6, 7, 8, 9]
    Sorted by creation time: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    

    如果您想看到我们确实对我们自己的对象而不是字符串进行了排序,您可以尝试更改toString 方法。一个例子:

        @Override
        public String toString() {
            return name + ' ' + created.atZone(ZoneId.of("Pacific/Niue"));
        }
    

    【讨论】:

    • 你能举个例子吗?你肯定会向我展示一些新的东西。
    • 我也试试这个
    猜你喜欢
    • 2019-02-03
    • 2013-09-09
    • 2019-08-02
    • 2017-05-22
    • 2017-09-07
    • 2012-05-30
    • 2019-08-18
    • 2011-03-11
    • 2016-08-28
    相关资源
    最近更新 更多