【问题标题】:Sort ArrayList of objects based on (dynamically changing) key根据(动态变化的)键对对象的 ArrayList 进行排序
【发布时间】:2014-04-25 18:18:04
【问题描述】:

我正在尝试根据动态变化的键对对象的 ArrayList 进行排序。

 public class My Objects {
 public String name;
 public int id;
 }

 String[] nameKeys = {"key1", "key2", "key3"};
 ArrayList<MyObjects> ObjectArray = new ArrayList<MyObjetcs>();

现在我想使用在“keys”变量中找到的任何键对 ObjectArray 进行排序。 用户将决定使用哪个密钥。

我已经为此困扰了几个小时,所以如果我能得到任何帮助,我将不胜感激。 谢谢

编辑:

ObjectArray.add( new MyObjects("key1", 1);
ObjectArray.add( new MyObjects("randomname", 2);
ObjectArray.add( new MyObjects("anothername", 3);
ObjectArray.add( new MyObjects("key1", 4);

sort("randomname", ObjectArray); //What I'd like to be able to do
for( MyObjects ob : ObjectArray)
area.append(ob.name+"->"+ob.id+"\n");



Result:
randoname->2
key1->1
key1->4
anothername->3

第二次编辑: 我从一开始就想解决这个问题。感谢大家的帮助。

【问题讨论】:

  • 该示例是否意味着您希望提供的键是第一个,其他的 - 按字典顺序排序?
  • 考虑一下当您向ObjectArray:ObjectArray.add(new MyObjects("xkey", 5); 添加额外元素时会发生什么。应该排在"randomname" 之后还是之前?
  • @AlexeyMalev 不完全是。相反,它根据第一个字母排序,如果两个单词以相同的字母开头,它会查看第二个字母,依此类推。
  • @user3574052 对不起,我不明白。 “r”作为第一个字母在“k”之前..
  • 尽管如此,我还是在我原来的想法中发现了一个漏洞。你是绝对正确的,现在我意识到为什么这篇文章如此令人困惑。感谢您的回答,它又回到了绘图板上。

标签: java sorting arraylist


【解决方案1】:

您可以通过几种不同的方式做到这一点。

首先是编写一个myObjectSort 函数,该函数获取您想要排序的键,并使用它通过将适当的Comparable 对象传递给排序来执行排序。

第二个是在一个对象中捕获它,该对象在构造时获取键(可能通过 setter)并通过相同的 Comparable 对象执行排序。

如果您提供更多关于键的实际作用以及您打算如何使用它们进行排序的信息,我可以提供代码。

【讨论】:

  • 基本上:这些键会告诉我要使用 ArrayList 中的什么对象。新的 MyObject("key1",1);新的 MyObject("key2",2);新的 MyObject("key3",3);如果我(用户)选择“key”,那么 arraylist 将按该字符串排序并以这个新的排序顺序显示。有意义吗?
  • 否,因为这不提供实际订购。如果用户要求列表按“key1”排序,并且您在 ArrayList 中列出了对象,那么结果列表应该是什么样的?
  • 排序将从“key1”开始,按自然顺序下降。如果它是“key3”,那将是相同的。正如我在另一条评论中所说,可能有多个对象具有相同的键。
  • 对,我要求您指定自然顺序是什么。如果用户选择“key3”,您的 ArrayList 的自然顺序是什么? (我很不清楚这个问题是否有一个很好的答案)。
  • 按字母顺序。因此,如果键是高字母 (z,x),低字母将排在最后 (a,b,c)
【解决方案2】:

我认为您可以为此使用Comparator

让我们假设用户选择了keys[0] 作为键排序需要基于的。

首先,创建一个Comparator 作为单独的类或匿名类。它应该有一个compare() 方法(我需要一个单独的方法):

public class KeyBasedComparator implements Comparator<MyObjects> {
    public final String key;

    public KeyBasedComparator(String key) {
        this.key = key;
    }

    public int compare(MyObjects object1, MyObjects object2) {
        if ("key1".equals(this.key)) {
            return new Integer(object1.id).compareTo(object2.id);
        } else if ("key2".equals(this.key)) {
            return object1.name.compareTo(object2.name);
        }
        //some other key-based logic possibly here
    }
}

好的,现在我们有了这个比较器。我们将对其进行排序:

Collections.sort(ObjectArray, new KeyBasedComparator(keys[0]));

【讨论】:

  • 所以让我们看看我是否理解这一点:您编写的 if 语句仅比较“key”字符串,并且要比较其他键,我必须为每个新键添加一个 else if。对吗?
  • 好吧,我猜 - 是的。您使用 intString 字段创建了 MyObjects 类 - 不清楚如何创建基于外部键的排序标准,所以我首先想到的是写的,也许是愚蠢的。也许如果你解释一下关键是如何影响你想要对对象进行排序的方式,我会想出一个更好的Comparator
  • 键被放置在一个 JComboBox 中。当用户选择其中一个键时,对象将按排序顺序打印在文本区域中。因此,如果用户选择了“key3”,则所有对象都将按该 ID (key3) 进行排序,然后呈现。顺便说一句,键不是唯一的,可能有多个对象具有相同的键。
  • 你能解释一下“将按那个id(key3)排序”是什么意思吗?我的意思是,您的班级中没有 key3 字段。
  • 在此示例中,“key3”是字符串名称的值。 ObjectArray.add( new MyObjects("key1", 1); ObjectArray.add( new MyObjects("anotherkey", 2); ObjectArray.add( new MyObjects("anotherkey", 4); 现在我想根据 ObjectArray 排序用户提供什么键。现在意识到使用“key1..3”对于我原来的例子来说不是最好的。很抱歉可能造成的混乱。我希望它们按字母顺序排序。所以在这个例子中如果选择“key1 " 作为排序的键,然后 "anotherkey" 将是最后一个对象,因为它以 "a" 开头。
【解决方案3】:

您可以创建不同的 Comparator 实现,如果您使用的是 Java 8,则可以使用 Stream API 并行或顺序运行它。

示例代码将是:

Stream<String> names2 = Stream.of("aBc", "d", "ef", "123456");
    List<String> reverseSorted = names2.sorted(Comparator.reverseOrder()).collect(Collectors.toList());
    System.out.println(reverseSorted); // [ef, d, aBc, 123456]

注意Comparator.reverseOrder()是java提供的比较器之一。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-23
    • 2021-02-07
    • 1970-01-01
    相关资源
    最近更新 更多