Java 如何通过计数排序对枚举进行排序?
例如,我想对枚举进行排序。我有一个对象,其键为Java 如何通过计数排序对枚举进行排序?,java,algorithm,sorting,enums,Java,Algorithm,Sorting,Enums,例如,我想对枚举进行排序。我有一个对象,其键为Enum 已更新 public class Main { public static void main(String[] args) throws Exception { Bean[] mass = new Bean[] { new Bean(new Object(), A), new Bean(new Object(), C), new Bean(new Object(), D), ne
Enum
已更新
public class Main {
public static void main(String[] args) throws Exception {
Bean[] mass = new Bean[] { new Bean(new Object(), A), new Bean(new Object(), C), new Bean(new Object(), D),
new Bean(new Object(), B), new Bean(new Object(), A) }; // 1, 3, 4, 2, 1
Arrays.sort(mass, new EnumComparator());
System.out.println(Arrays.toString(mass)); //[1, 1, 2, 3, 4]
}
}
class EnumComparator implements Comparator<Bean> {
@Override
public int compare(Bean o1, Bean o2) {
return o1.key.toString().compareTo(o2.key.toString());
}
}
class Bean {
public Object data;
public Enum key;
public Bean(Object data, Enum key) {
super();
this.data = data;
this.key = key;
}
@Override
public String toString() {
return key.toString();
}
}
enum MyEnum {
D("4"),
A("1"),
B("2"),
C("3");
private String index;
private MyEnum(String index) {
this.index = index;
}
@Override
public String toString() {
return index;
}
}
公共类主{
公共静态void main(字符串[]args)引发异常{
Bean[]mass=newbean[]{newbean(newobject(),A),newbean(newobject(),C),newbean(newobject(),D),
newbean(newobject(),B),newbean(newobject(),A)};//1,3,4,2,1
sort(mass,new enumparator());
System.out.println(Arrays.toString(mass));/[1,1,2,3,4]
}
}
类EnumComparator实现Comparator{
@凌驾
公共int比较(Bean o1,Bean o2){
返回o1.key.toString().compareTo(o2.key.toString());
}
}
类豆{
公共对象数据;
公共枚举密钥;
公共Bean(对象数据、枚举键){
超级();
这个数据=数据;
this.key=key;
}
@凌驾
公共字符串toString(){
return key.toString();
}
}
髓鞘{
D(“4”),
A(“1”),
B(“2”),
C(“3”);
私有字符串索引;
私有MyEnum(字符串索引){
这个指数=指数;
}
@凌驾
公共字符串toString(){
收益指数;
}
}
排序
数组。排序使用TimSort
或MergeSort
平均运行O(n log n)
。但是如果我们使用有限数量的常量(enum
),我们可以使用in timeO(n)
。在java
中是否有标准的机制来使用enum
的计数排序?如果您事先知道常量的顺序,您可以使用HashMap
来实现计数排序:
List<MyEnum> countingSort(MyEnum order[], List<MyEnum> input) {
HashMap<MyEnum, Integer> countMap = new HashMap<>();
for (MyEnum obj : input) {
countMap.put(obj, countMap.getOrDefault(obj, 0) + 1);
}
List<MyEnum> result = new ArrayList<>();
for (MyEnum obj : order) {
for (int i = 0; i < countMap.getOrDefault(obj, 0); ++i) {
result.add(obj);
}
}
return result;
}
public static void main (String[] args) {
MyEnum order[] = {A, B, C, D};
List<MyEnum> input = Arrays.asList(D, C, A, B, D, D, B, A, A, C, D);
List<MyEnum> res = countingSort(order, input);
}
List countingSort(MyEnum顺序[],列表输入){
HashMap countMap=新HashMap();
用于(MyEnum对象:输入){
countMap.put(obj,countMap.getOrDefault(obj,0)+1);
}
列表结果=新建ArrayList();
对于(MyEnum obj:订单){
对于(int i=0;i
这种方法的复杂性平均为O(n)
在问题的更新版本中,您正在询问。它类似于计数排序,但有自己的名称。我们需要对上面的算法进行一些修改。首先,我们需要用HashMap
替换HashMap
,并将所有Bean
对象存储在相应的列表中。然后在通过输入进行迭代之后,我们需要按照指定的顺序连接所有列表 这里有一个明显的非答案:不要
不要担心O(n)和O(n*log(n))。担心编写可以随时间而维护和增强的可读代码
有两种情况:
- n是如此之大以至于差异很重要。这意味着n可能是一个非常大的数。然后,你将面临一大堆其他更重要的问题,你应该首先关注这些问题。因为你的“处理链”中的每一步都很重要。在这种情况下,您必须仔细查看每个步骤,并确定如何对其进行优化(最有可能的是,您必须先进行测量,然后才能应用产生影响的优化)
- n是如此之小以至于。。。uups:n很小。这意味着我们首先谈论的是“少于毫秒”李>
长话短说:这听起来像是典型的早熟优化。唯一有效的答案是:专注于编写干净、优雅的代码来完成任务。然后用真实数据进行测量。然后决定是否需要采取进一步的行动(大多数情况下:不需要)。好的,我们不需要讨论应该使用O(n)
还是O(nlogn)
就足够了。不管怎样,也许您可以实现定制的计数排序
算法?(我不记得我知道的任何图书馆都有这个):
private静态void countSort(Bean[]mass){
List[]arr=(List[])新列表[MyEnum.values().length];
for(Bean:mass){
int pos=Integer.parseInt(bean.key.getIndex())-1;
如果(arr[pos]==null)
arr[pos]=新的ArrayList();
arr[pos].add(bean);
}
int i=0;
for(列表bean:arr)
for(Bean:Bean)
质量[i++]=bean;
}
您总是可以使用其他实用程序方法,而不是数组。sort()
或自己编写一个,但只需几个元素,这真的很重要吗?性能上的差异几乎可以忽略不计。这并不是说计数排序实际上更适合于枚举。我更愿意问一个问题,如果对于有限的枚举集,在O(n)
或O(n log n)
中排序会有什么不同。虽然与渐近分析无关,但常数对于运行代码来说可能非常有趣。我有一个对象数组,其中Enum
作为键,我需要排序。Java中没有计算排序的标准机制,period。虽然这是一个相当琐碎的算法来写自己,你可能会在网上找到无数这样的例子。我不同意你。如果有一个对象使用Enum作为键,并且需要使用这些对象对数组进行排序,则需要记住相同对象的数量,并从必要的索引填充新数组,这并不是那么简单。是的,一切都是正确的。但在您的解决方案中,我们用相同的对象(而不是真实对象)填充列表)。假设一个复合对象包含一个Enum
作为键字段,我们需要所有其余的信息。例如objA{MyEnum Enum=MyEnum.a,public Integer index=**1**)
和objB{MyEnum enu
private static void countSort(Bean[] mass) {
List<Bean>[] arr = (List<Bean>[])new List[MyEnum.values().length];
for (Bean bean : mass) {
int pos = Integer.parseInt(bean.key.getIndex()) - 1;
if (arr[pos] == null)
arr[pos] = new ArrayList<>();
arr[pos].add(bean);
}
int i = 0;
for (List<Bean> beans : arr)
for (Bean bean : beans)
mass[i++] = bean;
}