<String> 按创建顺序对 ArrayList 进行排序 [Android/Java]



所以我正在开发一个应用程序,我有一个按钮,用户单击该按钮即可循环浏览数组列表的三个排序集。我有它,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();
}
}

最新答案

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

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()
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"));
}

最新更新