===主要编辑(和次要编辑)===
我完全重写了我几天前提交的代码,因为它是基于其他两个代码不那么深思熟虑的代码,这是gitgo提出的一个非常不合适的想法。我没有足够的研究能力。
尽管如此,@ F. Böller非常友好地回答了关于我的原始代码的问题,并说我需要在此上下文中定义comparator
:
TreeSet<ArrayList<Integer>> hs = new TreeSet<>(comparator);
。
这是我对Google java treesort comparator所需的所有鼓励,并根据我在那里看到的内容进行了修订。这一点都不容易,我承认我仍然不太明白为什么下面的语法基本上都是我需要的,但是如果没有Googled链接上面的例子,我就永远不会想到它。
TreeSet<Leaf> theTreeSet = new TreeSet<>(new HowToCompareLeaves());
===次要编辑 - 以下行错误:
无论如何,下面的代码效果很好(根据每个“叶子”中的第一个元素排序)。
===以下行是正确的:
无论如何,下面的代码效果很好(对每个“叶子”中的所有元素进行排序和比较)。
===结束次要编辑===
但是,如果有人可以解释(之前从未使用过TreeSet
的人)上面的行实际上做了什么,我会很感激。它似乎定义了一个新的实例,它定义为比较ar
组成的数据项的方法......是吗?它是新TreeSet
的构造函数,需要定义如何将新元素分类到自身中吗?
package treed;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetExample {
public static final int NR = 4, NC = 3;
public static void main(String a[])
{
ArrayList<Leaf> ar = new ArrayList<>(NR);
for (int i = 0; i < NR; i++)
ar.add(new Leaf());
System.out.println("Pre-sort:");
for(int i = 0; i < NR; i++)
System.out.println(ar.get(i));
TreeSet<Leaf> theTreeSet = new TreeSet<>(new HowToCompareLeaves());
System.out.println("\nPost-sort:");
for (int i = 0; i < NR; i++)
theTreeSet.add(ar.get(i));
for(Leaf e:theTreeSet)
System.out.println(e);
}
}
class HowToCompareLeaves implements Comparator<Leaf>
{
@Override
public int compare(Leaf e, Leaf f)
{
if(e.row.get(0) > f.row.get(0)) return 1;
if(e.row.get(0) < f.row.get(0)) return -1;
return 0;
}
}
class Leaf
{
ArrayList<Integer> row;
Leaf()
{
row = new ArrayList<>(TreeSetExample.NC);
for (int i = 0; i < TreeSetExample.NC; i++)
row.add((int)(Math.random()*89 + 10));
}
public String toString()
{
String s = "";
for (int i = 0; i < TreeSetExample.NC; i++) {
s += row.get(i) + "...";
}
return s;
}
}
===编辑结束;休息是垃圾=======================
我正在关注一个关于ArrayList的ArrayList的一个新的未回答的问题,该问题需要进行非重复数据删除和排序。一个答案建议使用HashSet
来删除重复项,但不会排序,因为下面的工作代码确认了。
import java.util.ArrayList;
import java.util.HashSet;
public class TwoDimArrayList {
static ArrayList<Integer> r;
static ArrayList<ArrayList<Integer>> a2D = new ArrayList<>();
public static void main(String[] args) {
for (int i = 0; i < 5; i++) {
r = new ArrayList<>();
for (int j = 0; j < 3; j++)
r.add((int)(Math.random() * 89 + 11));
a2D.add(r);
}
for (int i = 0; i < a2D.size(); i++){
for (int j = 0; j < a2D.get(i).size(); j++)
System.out.print(a2D.get(i).get(j) + "\t");
System.out.println("...");
}
HashSet<ArrayList<Integer>> hs = new HashSet<>(a2D.size());
for (int i = 0; i < a2D.size(); i++)
hs.add(a2D.get(i));
a2D.clear();
for (int i = 0; i < hs.size(); i++)
a2D.add((ArrayList<Integer>) hs.toArray()[i]);
for (int i = 0; i < a2D.size(); i++){
for (int j = 0; j < a2D.get(i).size(); j++)
System.out.print(a2D.get(i).get(j) + "\t");
System.out.println();
}
}
}
我尝试将HashSet
更改为TreeSet
,因为后者提供了排序:
TreeSet<ArrayList<Integer>> hs = new TreeSet<>(a2D.size());
这给出了错误:cannot infer arguments for TreeSet
。所以我最终摆脱了它:
TreeSet<ArrayList<Integer>> hs = new TreeSet<>();
但我在这一行得到错误:
hs.add(a2D.get(i));
Exception in thread "main" java.lang.ClassCastException: java.util.ArrayList cannot be cast to java.lang.Comparable
对此有一些简单的解决方法吗?或者希望TreeSet
进行排序本身就是错误的? (我是新手,以防有人想知道......)
答案 0 :(得分:7)
TreeSet不知道如何对ArrayLists进行排序,因为列表没有自然排序。它应该将列表与值的最小值,列表的平均值或其他值进行比较吗? 要使TreeSet了解要排序的内容,必须在构造函数中添加一个比较器:
TreeSet<ArrayList<Integer>> hs = new TreeSet<>(comparator);
比较器必须实现接口Comparator<ArrayList>
。在这里您可以定义如何订购ArrayList。
如果你不添加一个比较器,TreeSet会隐式地期望ArrayList实现Comparable-Interface,而它不会这样做。
答案 1 :(得分:1)
如果你想对List<Integer>
的列表进行排序,那么你必须为此自己编写逻辑。 Java无法自动推断出这种排序。
TreeSet
使用元素的自然顺序来保持整个Set的排序。但是在你的情况下,这种自然顺序是未定义的,因此是ClassCastException
。