按名称对ArrayList项目进行排序



我试图根据特定索引上的项目名称重新排列阵列清单。

我的清单目前是:

"SL"
"TA"
"VP"
"SP"
"PR"

我想重新排列它们:

"SL"
"SP"
"TA"
"PR"
"VP"

,但基于名称而不是索引。

我尝试了以下方法:

for (int i=0; i< list.size(); i++){
    if (list.get(i).getCategoryName().equals("SL")){
        orderedDummyJSONModelList.add(list.get(i));
    }
}
for (int i=0; i< list.size(); i++){
    if (list.get(i).getCategoryName().equals("SP")){
        orderedDummyJSONModelList.add(list.get(i));
    }
}
for (int i=0; i< list.size(); i++){
    if (list.get(i).getCategoryName().equals("TA")){
        orderedDummyJSONModelList.add(list.get(i));
    }
}
for (int i=0; i< list.size(); i++){
    if (list.get(i).getCategoryName().equals("PR")){
        orderedDummyJSONModelList.add(list.get(i));
    }
}
for (int i=0; i< list.size(); i++){
    if (list.get(i).getCategoryName().equals("VP")){
       orderedDummyJSONModelList.add(list.get(i));
    }
}

效果很好,但是我想知道是否有更有效的方法可以在1中进行循环或函数。我不想这样做:

orderedDummyJSONModelList.add(list.get(0));
orderedDummyJSONModelList.add(list.get(3));
orderedDummyJSONModelList.add(list.get(1));
orderedDummyJSONModelList.add(list.get(4));
orderedDummyJSONModelList.add(list.get(2));

也有效。有什么想法吗?

您可以将Collection.Sort方法用作Collection.Sort(list),因为listList<String>,您会没事的。但是,如果您想实现一个新的比较器:

Collections.sort(list, new NameComparator());
class NameComparator implements Comparator<String> { //You can use classes
    @Override
    public int compare(String a, String b) { //You can use classes
        return a.compareTo(b); 
    }
}

编辑:

您可以根据需要定义类比较器:

class ClassComparator implements Comparator<YourClass> { //You can use classes
    @Override
    public int compare(YourClass a, YourClass b) { //You can use classes
        return a.name.compareTo(b.name); 
    }
}

这里是:您需要清楚自己的要求

换句话说:当然,人们可以在列表中存储的对象上进行洗牌。但是:可能您想做编程

换句话说:正确的方法是使用内置的集合排序机制,但是提供自定义比较器。

含义:您最好找到一个定义如何来自

算法

" SL" ta" VP" SP" PR"

to

" SL" SP" ta" PR" VP"

算法应该进入您的比较器实现!

重点是:您首先有一些List<X>。X对象提供了某种方法来检索您在此处显示的那些字符串。因此,您必须创建一个在x值上工作的Comparator<X>;并使用某些的意思是到达那些字符串值;并以此为基础,您决定x1是否比某些x2对象!

这是仅针对给定输出工作的问题的答案。如果List包含其他任何内容,这可能会破坏您的订购,因为没有关于如何订购的规则,而PR最终随机出现。

public static void main(String[] args) {
    List<String> justSomeNoRuleOrderingWithARandomPRInside = new ArrayList<String>();
    justSomeNoRuleOrderingWithARandomPRInside.add("SL");
    justSomeNoRuleOrderingWithARandomPRInside.add("TA");
    justSomeNoRuleOrderingWithARandomPRInside.add("VP");
    justSomeNoRuleOrderingWithARandomPRInside.add("SP");
    justSomeNoRuleOrderingWithARandomPRInside.add("PR");
    java.util.Collections.sort(justSomeNoRuleOrderingWithARandomPRInside, new NameComparator());
    for(String s : justSomeNoRuleOrderingWithARandomPRInside) {
        System.out.println(s);
    }
}
static class NameComparator implements Comparator<String> { //You can use classes
    @Override
    public int compare(String a, String b) { //You can use classes
        // Lets just add a T in front to make the VP appear at the end 
        // after TA, because why not
        if (a.equals("PR")) {
            a = "T"+a;
        } else if(b.equals("PR")) {
            b = "T"+b;
        }
        return a.compareTo(b);
    }
}

o/p

SL
SP
TA
PR
VP

但老实说,这个解决方案是胡扯,没有任何明确的规则,就这些解决方案的订购方式都将注定要尽快失败,就像@ghostcat试图解释的那样。

这个

怎么样
// define the order
List<String> ORDER = Arrays.asList("SL", "SP", "TA", "PR", "VP");
List<MyObject> list = ...
list.sort((a, b) -> {
    // lamba syntax for a Comparator<MyObject>
    return Integer.compare(ORDER.indexOf(a.getString()), ORDER.indexOf(b.getString());
});

请注意,这将使排序列表开头的顺序列表中未定义的字符串。这可能是可以接受的,也可能是不可接受的 - 可能值得检查是否仅出现有效的字符串(即订单成员),因为MyObject.getString()。

  1. 使用hashmap存储所有字符串的重量(hashmap的值较高意味着该字符串应稍后出现在最终列表中)。
  2. 使用hashmap,因此您以后还可以将其扩展到其他字符串。将来会更容易增强。
  3. 最后,使用自定义比较器进行。

必需的设置:

       List<String> listOfStrings = Arrays.asList("SL", "TA", "VP", "SP", "PR");
        HashMap<String, Integer> sortOrder = new HashMap<>();
        sortOrder.put("SL", 0);
        sortOrder.put("TA", 1);
        sortOrder.put("VP", 2);
        sortOrder.put("SP", 3);
        sortOrder.put("PR", 4);

流:

        List<String> sortedList = listOfStrings.stream().sorted((a, b) -> {
            return Integer.compare(sortOrder.get(a), sortOrder.get(b));
        }).collect(Collectors.toList());
        System.out.println(sortedList);

非流程:

        Collections.sort(listOfStrings, (a, b) -> {
            return Integer.compare(sortOrder.get(a), sortOrder.get(b));
        });
OR
        listOfStrings.sort((a, b) -> {
            return Integer.compare(sortOrder.get(a), sortOrder.get(b));
        });
        System.out.println(listOfStrings);

输出

[SL, TA, VP, SP, PR]

您可以使用LinkedHashMap构建索引图。这将用于查找使用项目的类别名称进行排序的顺序。

tockorting

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class ItemSorting {
    public static void main(String[] args) {
        List<Item> list = new ArrayList<Item>();
        IndexMap indexMap = new IndexMap("SL", "SP", "TA", "PR", "VP");
        ItemComparator itemComparator = new ItemComparator(indexMap);
        list.add(new Item("SL"));
        list.add(new Item("TA"));
        list.add(new Item("VP"));
        list.add(new Item("SP"));
        list.add(new Item("PR"));
        Collections.sort(list, itemComparator);
        for (Item item : list) {
            System.out.println(item);
        }
    }
}

itemcomparator

import java.util.Comparator;
public class ItemComparator implements Comparator<Item> {
    private IndexMap indexMap;
    public IndexMap getIndexMap() {
        return indexMap;
    }
    public void setIndexMap(IndexMap indexMap) {
        this.indexMap = indexMap;
    }
    public ItemComparator(IndexMap indexMap) {
        this.indexMap = indexMap;
    }
    @Override
    public int compare(Item itemA, Item itemB) {
        if (itemB == null) return -1;
        if (itemA == null) return 1;
        if (itemA.equals(itemB)) return 0;
        Integer valA = indexMap.get(itemA.getCategoryName());
        Integer valB = indexMap.get(itemB.getCategoryName());
        if (valB == null) return -1;
        if (valA == null) return 1;
        return valA.compareTo(valB);
    }
}

indexmap

import java.util.LinkedHashMap;
public class IndexMap extends LinkedHashMap<String, Integer> {
    private static final long serialVersionUID = 7891095847767899453L;
    public IndexMap(String... indicies) {
        super();
        if (indicies != null) {
            for (int i = 0; i < indicies.length; i++) {
                this.put(indicies[i], new Integer(i));
            }
        }
    }
}

项目

public class Item {
    private String categoryName;
    public Item(String categoryName) {
        super();
        this.categoryName = categoryName;
    }
    public String getCategoryName() {
        return categoryName;
    }
    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((categoryName == null) ? 0 : categoryName.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj) return true;
        if (obj == null) return false;
        if (getClass() != obj.getClass()) return false;
        Item other = (Item) obj;
        if (categoryName == null) {
            if (other.categoryName != null) return false;
        } else if (!categoryName.equals(other.categoryName)) return false;
        return true;
    }
    @Override
    public String toString() {
        return String.format("Item { "categoryName" : "%s" }", categoryName);
    }
}

结果

Item { "categoryName" : "SL" }
Item { "categoryName" : "SP" }
Item { "categoryName" : "TA" }
Item { "categoryName" : "PR" }
Item { "categoryName" : "VP" }

您coud定义了这样的辅助方法:

public static int get(String name) {
    switch (name) {
    case "SL":
        return 1;
    case "SP":
        return 2;
    case "TA":
        return 3;
    case "PR":
        return 4;
    case "VP":
        return 5;
    default:
        return 6;
    }
}

并在您的主要方法中写入类似:

ArrayList<String> al = new ArrayList<>();
al.add("SL");
al.add("TA");
al.add("VP");
al.add("SP");
al.add("PR");
Collections.sort(al, (o1, o2) -> return get(o1) - get(o2); );
al.forEach((s) -> System.out.println(s));

您可以创建维护位置的地图。当您遍历未排序的列表时,只需获取该字符串值的位置并插入新数组(不是ArrayList),然后在需要时,您可以将该数组转换为ArrayList。示例代码:

Map<String,Integer> map = new HashMap<>(); //you can may be loop through and make this map
map.put("SL", 0);
map.put("SP", 1);
map.put("TA",2);
map.put("PR",3);
map.put("VP",3);
List<String> list1 // your unordered list with values in random order
String[] newArr =  new String[list1.size()];
for(String strName: list1){
    int position  = map.get(strName);
    arr[position] = strName;
}
//newArr has ordered result.

最新更新