小说的内容据书上说JDK1.7展开解析,之所以选取这几个本子,是因为1.8的多少类做了改观,扩大了阅读的难度,尽管是1.7,可是对于1.8做了第一退换的情节,文章也会开展求证。

Set集结中的treeSet难题:cannot be cast to java.lang.Comparable;

Set集合中的treeSet难点:cannot be cast to java.lang.Comparable;

TreeSet完毕了SortedSet接口,它是八个静止的集结类,TreeSet的最底层是透过TreeMap达成的。TreeSet并不是依照插入的逐个来排序,而是依据实际的值的分寸来排序。TreeSet也支撑三种排序格局:

原理:

Set不保留重复的因素,与Collection类似,只是作为分裂,Set是依靠对象的值来明确归属性的。对结果排序,日常选取TreeSet。


TreeSet是借助TreeMap来实现的。
TreeSet是二个不改变集中,TreeSet中的成分将遵照升序排列,缺省是根据自然排序实行排列,意味着TreeSet中的成分要贯彻Comparable接口。大概有三个自定义的比较器,
我们能够在结构TreeSet对象时,传递完毕Comparator接口的相比器对象。

  • TreeSet存款和储蓄对象的时候, 可以排序, 但是索要内定排序的算法
  • Integer能排序(有暗许顺序), String能排序(有暗中同意顺序),
    自定义的类存款和储蓄的时候出现万分(未有各种)
  • 假定想把自定义类的靶子存入TreeSet举行排序 那么必得实现Comparable接口 在类上implement Comparable重写compareTo()方法在章程钦命义相比较算法, 依照大小关系, 再次回到正数负数或零在使用TreeSet存款和储蓄对象的时候, add()方法内部就能自行调用compareTo()方法进行比较

    ==cannot be cast to
    java.lang.Comparable==
    ,境遇那么些可怜错误,就是说treeMap(恐怕treeSet)并不知道该怎么着开展排序,化解这么些极其有三种艺术:

  1. 在构造TreeMap时钦赐三个相比器,那一个相比较器用于比较七个值,並且重临二个整数值作为她们的可比结实。
  2. 正是key实现Comparable接口。同等对待写compareTo()方法;依照大小关系,
    重返正数负数或零

@Override
    public int compareTo(Resources o) {
        if (o.id == this.id) {
            return 0;
        } else if (this.id > o.id) {
            return 1;
        } else
            return -1;
    }

原理:

Set不保留重复的成分,与Collection类似,只是行为不一致,Set是依照对象的值来规定归属性的。对结果排序,日常采取TreeSet。


TreeSet是注重TreeMap来完结的。
TreeSet是八个平稳集中,TreeSet中的成分将如约升序排列,缺省是依照自然排序实行排列,意味着TreeSet中的成分要兑现Comparable接口。或然有一个自定义的比较器,
咱俩得以在布局TreeSet对象时,传递完成Comparator接口的相比较器对象。

  • TreeSet存款和储蓄对象的时候, 能够排序, 但是内需内定排序的算法
  • Integer能排序(有暗中认可顺序), String能排序(有默许顺序),
    自定义的类存款和储蓄的时候出现极度(未有各类)
  • 若果想把自定义类的指标存入TreeSet进行排序 那么必需实现Comparable接口 在类上implement Comparable重写compareTo()方法在点子内定义相比较算法, 依据大小关系, 重回正数负数或零在使用TreeSet存储对象的时候, add()方法内部就能够活动调用compareTo()方法开展相比

    ==cannot be cast to
    java.lang.Comparable==
    ,碰到那个这些错误,就是说treeMap(只怕treeSet)并不知道该怎么进展排序,化解这么些可怜有二种办法:

  1. 在结构TreeMap时钦点贰个相比器,这些比较器用于相比较八个值,而且再次回到一个整数值作为她们的相比较结实。
  2. 即是key达成Comparable接口。因人而异写compareTo()方法;遵照大小关系,
    重返正数负数或零

@Override
    public int compareTo(Resources o) {
        if (o.id == this.id) {
            return 0;
        } else if (this.id > o.id) {
            return 1;
        } else
            return -1;
    }
  • 自然排序
  • 自定义排序
yzc579亚洲城官网,此起彼落关系
java.lang.Object java.util.AbstractCollection<E> java.util.AbstractSet<E> java.util.TreeSet<E> 
贯彻接口
Serializable, Cloneable, Iterable<E>, Collection<E>, NavigableSet<E>, Set<E>, SortedSet<E> 
Kit性子
private transient NavigableMap<E,Object> m; //存放元素的集合private static final Object PRESENT = new Object(); //m中key 对应的value 
根本措施深度深入分析
构造方法
//相同包下可以访问的构造方法,将指定的m赋值为m TreeSet(NavigableMap<E,Object> m) { this.m = m;}//无参构造方法,创建一个空的TreeMap对象,并调用上面的构造方法public TreeSet() { this(new TreeMap<E,Object>;}//指定比较器,并用指定的比较器创建TreeMap对象public TreeSet(Comparator<? super E> comparator) { this(new TreeMap<>(comparator));}//将指定的集合C转化为TreeSetpublic TreeSet(Collection<? extends E> c) { this(); addAll;}//将SortedMap中的元素转化为TreeMap对象public TreeSet(SortedSet<E> s) { this(s.comparator; addAll;}

由此上边的构造方法,能够观望TreeSet的尾部是用TreeMap达成的。在构造方法中会创制三个TreeMap实例,用于贮存元素,别的TreeSet是雷打不动的,也提供了制订相比较器的构造函数,若无提供相比较器,则运用key的当然顺序进行比十分大小,假诺钦点的相比器,则动用钦命的比较器,实行key值大小的相比较。

add()方法和remove()方法都对比的简便都以调用TreeMap的方法进行得以实现。此处不在单独列出

源码剖判
public class TreeSet<E> extends AbstractSet<E> implements NavigableSet<E>, Cloneable, java.io.Serializable{ //存放元素的map对象 private transient NavigableMap<E,Object> m; //key-value ,不同的键都会对象相同的value, value = PRESENT private static final Object PRESENT = new Object(); //指定的map对象 TreeSet(NavigableMap<E,Object> m) { this.m = m; } //无参构造方法,初始化一个TreeMap对象 public TreeSet() { this(new TreeMap<E,Object>; } //构造方法,指定比较器 public TreeSet(Comparator<? super E> comparator) { this(new TreeMap<>(comparator)); } //将集合中的元素转化为TreeSet存储 public TreeSet(Collection<? extends E> c) { this(); addAll; } //构造方法,SortedSet转化为TreeSet存储,并使用SortedSet的比较器 public TreeSet(SortedSet<E> s) { this(s.comparator; addAll; } //遍历方法,返回m.keyset集合 public Iterator<E> iterator() { return m.navigableKeySet().iterator(); } //逆序排序的迭代器 public Iterator<E> descendingIterator() { return m.descendingKeySet().iterator(); } /** * @since 1.6 */ public NavigableSet<E> descendingSet() { return new TreeSet<>(m.descendingMap; } //返回 m 包含的键值对的数量 public int size() { return m.size(); } //是否为空 public boolean isEmpty() { return m.isEmpty(); } //是否包含指定的key public boolean contains { return m.containsKey; } //添加元素,调用m.put方法实现 public boolean add { return m.put(e, PRESENT)==null; } //删除方法,调用m.remove()方法实现 public boolean remove { return m.remove==PRESENT; } //清除集合 public void clear() { m.clear(); } //将一个集合中的所有元素添加到TreeSet中 public boolean addAll(Collection<? extends E> c) { // Use linear-time version if applicable if ==0 && c.size() > 0 && c instanceof SortedSet && m instanceof TreeMap) { SortedSet<? extends E> set = (SortedSet<? extends E>) c; TreeMap<E,Object> map = (TreeMap<E, Object>) m; Comparator<? super E> cc = (Comparator<? super E>) set.comparator(); Comparator<? super E> mc = map.comparator(); if (cc==mc || (cc != null && cc.equals { map.addAllForTreeSet(set, PRESENT); return true; } } return super.addAll; } //返回子集合,通过 m.subMap()方法实现 public NavigableSet<E> subSet(E fromElement, boolean fromInclusive, E toElement, boolean toInclusive) { return new TreeSet<>(m.subMap(fromElement, fromInclusive, toElement, toInclusive)); } //返回set的头部 public NavigableSet<E> headSet(E toElement, boolean inclusive) { return new TreeSet<>(m.headMap(toElement, inclusive)); } //返回尾部 public NavigableSet<E> tailSet(E fromElement, boolean inclusive) { return new TreeSet<>(m.tailMap(fromElement, inclusive)); } //返回子Set public SortedSet<E> subSet(E fromElement, E toElement) { return subSet(fromElement, true, toElement, false); } //返回set的头部 public SortedSet<E> headSet(E toElement) { return headSet(toElement, false); } //返回set的尾部 public SortedSet<E> tailSet(E fromElement) { return tailSet(fromElement, true); } //返回m使用的比较器 public Comparator<? super E> comparator() { return m.comparator(); } //返回第一个元素 public E first() { return m.firstKey(); } //返回最后一个元素 public E last() { return m.lastKey(); } //返回set中小于e的最大的元素 public E lower { return m.lowerKey; } //返回set中小于/等于e的最大元素 public E floor { return m.floorKey; } //返回set中大于/等于e的最大元素 public E ceiling { return m.ceilingKey; } //返回set中大于e的最小元素 public E higher { return m.higherKey; } //获取TreeSet中第一个元素,并从Set中删除该元素 public E pollFirst() { Map.Entry<E,?> e = m.pollFirstEntry(); return (e == null) ? null : e.getKey(); } //获取TreeSet中最后一个元素,并从Set中删除该元素 public E pollLast() { Map.Entry<E,?> e = m.pollLastEntry(); return (e == null) ? null : e.getKey(); } //克隆方法 public Object clone() { TreeSet<E> clone = null; try { clone = (TreeSet<E>) super.clone(); } catch (CloneNotSupportedException e) { throw new InternalError(); } clone.m = new TreeMap<>; return clone; } //将对象写入到输出流中。 private void writeObject(java.io.ObjectOutputStream s) throws java.io.IOException { // Write out any hidden stuff s.defaultWriteObject(); // Write out Comparator s.writeObject(m.comparator; // Write out size s.writeInt; // Write out all elements in the proper order. for (E e : m.keySet s.writeObject; } //从输入流中读取对象的信息 private void readObject(java.io.ObjectInputStream s) throws java.io.IOException, ClassNotFoundException { // Read in any hidden stuff s.defaultReadObject(); // Read in Comparator Comparator<? super E> c = (Comparator<? super E>) s.readObject(); // Create backing TreeMap TreeMap<E,Object> tm; if  tm = new TreeMap<>(); else tm = new TreeMap<>; m = tm; // Read in size int size = s.readInt(); tm.readTreeSet(size, s, PRESENT); } //序列化版本号 private static final long serialVersionUID = -2479143000061671589L;}

TreeSet是三个萧规曹随的集结,基于TreeMap实现,援助三种排序情势:自然排序和定制排序。TreeSet是非同步的,线程不安全的。

少年听雨歌楼上,红烛昏罗帐。 壮年听雨客舟中,江阔云低,断雁叫西风。感谢支持! ---起个名忒难

Author

发表评论

电子邮件地址不会被公开。 必填项已用*标注