首先,如果想对有序容器按自己的意愿排序,可以使用Collections.sort(/*容器*/ , /*在这里定义一个Comparator的派生类*/)在派生类里重载compare
import java.util.*;
public class Main {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<Integer, String>();
map.put(1,"a");
map.put(4,"d");
map.put(2,"b");
map.put(3,"c");
map.put(5,"e");
System.out.println(map);
ArrayList<Map.Entry<Integer,String>> al = new ArrayList<>(map.entrySet());
Collections.sort(al,new Comparator<Map.Entry<Integer,String>>() {
public int compare(Map.Entry<Integer,String> e1,Map.Entry<Integer,String> e2) {
if(e1.getKey()<e2.getKey()) return 1;
else if (e1.getKey()>e2.getKey()) return -1;
else return 0;
}});
Map<Integer,String> map2 = new LinkedHashMap<>();
for (Map.Entry<Integer,String> me: al) {
map2.put(me.getKey(),me.getValue());
}
System.out.println(map2);
}
}
然后,如果我们想改变Set容器中相等的原则,可以在Set保存的类中重载hashCode和equals,hashCode使用Java自带的一些基本类的hashCode生成,equals自己定义,关于重载这一部分,我们可以使用内部匿名类(详情见代码),这样可以不影响我们的类在别的地方的使用。如果我们的类实现了很多接口,可以使用代码块中的内部类实现这个。当然这两种做法需要新创建对象,不能使用原有对象。同时发现了一个细节,HashSet添加一个相同元素时不会覆盖原有元素,而且会用当前保存元素作为比较的第二项。
import java.util.*;
public class Main {
public static void main(String[] args) {
String str = "a s a f f s e e e e w q";
String []sa = str.split(" ");
Set<Combine> s = new HashSet<>();
for (String st: sa) {
s.add(new Combine(st) { //这是我第一次使用内部匿名类,这是一个很好的做法,这样equals可以根据需要定制不同的做法
public int hashCode() { //使用String的hashCode构造自己的hashCode,这样可以保证相同的字符串得到的结果相同
return str.hashCode()*count;
}
public boolean equals(Object ob) {
if (this.str.compareTo(((Combine)ob).str)==0) {
//++this.count;
++((Combine)ob).count; //这个结论是错误的(这里我们可以发现如果有相同的新的类加入set,会覆盖原有的)
//应该是每次都用已有元素做被比较的那个一个,并不替换掉已有元素
return true;
}
else return false;
}
});
s.add(new Combine(st)); //可以看到这里就没有定制的特性
}
Iterator<Combine> ic = s.iterator();
while (ic.hasNext()) {
Combine c = ic.next();
System.out.println(c.count);
System.out.println(c.str);
}
}
}
class Combine implements Comparable<Combine> { //但是内部匿名类是由短板的,他不能继承和实现多个接口,所以这里只能在基类实现一个接口,
//如果想有更好的实现可以使用一个代码块内部类实现
public int compareTo(Combine cb) { //不过compareTo是用于排序的HashSet不排序,所以在这里用不上
if (this.str.compareTo(cb.str)==0) ++count;
return this.str.compareTo(cb.str);
}
Combine(String st) {str = st;}
String str;
int count = 1;
}