精华内容
下载资源
问答
  • 主要介绍了TreeSet判断重复元素解析及代码示例,具有一定借鉴价值,需要的朋友可以参考下
  • TreeSet判断重复元素

    千次阅读 2017-11-03 10:25:51
    TreeSet的底层是TreeMap的keySet(),而TreeMap是基于红黑树实现的,红黑树是一种平衡二叉查找树,它能保证任何一...显然元素在插入TreeSet时compareTo()方法要被调用,所以TreeSet中的元素要实现Comparable接口。TreeSe

    TreeSet的底层是TreeMap的keySet(),而TreeMap是基于红黑树实现的,红黑树是一种平衡二叉查找树,它能保证任何一个节点的左右子树的高度差不会超过较矮的那棵的一倍。

    TreeMap是按key排序的,所以TreeSet中的元素也是排好序的。显然元素在插入TreeSet时compareTo()方法要被调用,所以TreeSet中的元素要实现Comparable接口。TreeSet作为一种Set,它不允许出现重复元素。TreeSet是用compareTo()来判断重复元素的,而非equals(),看下面代码。

    import java.util.TreeSet;


    import org.junit.Test;


    public class TestTreeSet {


        class Combine implements Comparable<Combine> {
            private int p1;
            private int p2;


            public Combine(int p1, int p2) {
                this.p1 = p1;
                this.p2 = p2;
            }


            @Override
            public int hashCode() {
                return p1 * 31 + p2;
            }


            @Override
            public boolean equals(Object obj) {
                System.out.print("whether equal " + this + " and " + obj);
                boolean rect = false;
                if (obj instanceof Combine) {
                    System.out.println("whether equal " + this + " and " + obj);
                    Combine other = (Combine) obj;
                    rect = (this.p1 == other.getP1() && this.p2 == other.getP2());
                }
                System.out.println(": " + rect);
                return rect;
            }


            @Override
            public int compareTo(Combine o) {
                System.out.print("compare " + this + " and " + o);
                // 排序时只考虑p1
                if (this.p1 < o.p1) {
                    System.out.println(", return -1");
                    return -1;
                } else if (this.p1 > o.p1) {
                    System.out.println(", return 1");
                    return 1;
                } else {
                    System.out.println(", return 0");
                    return 0;
                }
            }


            @Override
            public String toString() {
                return "(" + p1 + "," + p2 + ")";
            }


            public int getP1() {
                return p1;
            }


            public void setP1(int p1) {
                this.p1 = p1;
            }


            public int getP2() {
                return p2;
            }


            public void setP2(int p2) {
                this.p2 = p2;
            }


        }


        @Test
        public void test() {
            Combine c1 = new Combine(1, 2);
            Combine c2 = new Combine(1, 2);
            Combine c3 = new Combine(1, 3);
            Combine c4 = new Combine(5, 2);


            TreeSet<Combine> set = new TreeSet<Combine>();
            set.add(c1);
            set.add(c2);
            set.add(c3);
            set.add(c4);
            while (!set.isEmpty()) {    //按顺序输出TreeSet中的元素
                Combine combine = set.pollFirst();
                System.out.println(combine.getP1() + "\t" + combine.getP2());
            }
        }
    }

    输出:

    compare (1,2) and (1,2), return 0
    compare (1,2) and (1,2), return 0
    compare (1,3) and (1,2), return 0
    compare (5,2) and (1,2), return 1
    1 2
    5 2

    我们看到不论compareTo()返回的是不是相等,equals()方法都没有被调用。

    转载地址
    展开全文
  • 目录TreeSet的继承关系TreeSet任何判断重复元素改写Comparator添加重复元素以及出现的问题 TreeSet的继承关系 由上图可以看出TreeSet继承了AbstractSet抽象类,实现了NavigableSet接口。 TreeSet的本质是一个有序...

    TreeSet的继承关系

    在这里插入图片描述

    • 由上图可以看出TreeSet继承了AbstractSet抽象类,实现了NavigableSet接口。
    • TreeSet的本质是一个有序的,并且没有重复元素的集合,它是通过TreeMap实现的。TreeSet中含有一个"NavigableMap类型的成员变量"m,而m实际上是TreeMap的实例

    TreeSet任何判断重复元素

    • 由于TreeSet是通过TreeMap实现的,它添加的元素实际上就是TreeMap的Key值
      在这里插入图片描述
      在这里插入图片描述
    • 而TreeMap在判断是否有相同Key值时,是使用comparator来比较两个对象是否相等的,而非equal()方法比较。
      在这里插入图片描述
    • 因此在向TreeSet中添加元素时,即使两个元素对象的Hash值不同,但是通过Comparator比较后结果为相同,依然会添加失败。
    • 现在我们来创建一个TreeSet,里面储存的元素类型为数组,这个数组包含两个值,我们让第一个值均不一样,而第二个值均为0,而comparator比较的是第二个值的大小,我们尝试一下添加多个元素,查看结果。
    public class Test {
        public static void main(String[] args) {
            TreeSet<int[]> treeSet = new TreeSet<>(new Comparator<int[]>() {
                @Override
                public int compare(int[] o1, int[] o2) {
                    return o1[1]-o2[1];
                }   //比较第二个值的大小
            });
            for (int i = 0; i < 10; i++) {
                treeSet.add(new int[]{i,0});
            }   //第一个值均不一样(0~10递增),第二个值均为0
            for (int[] ints : treeSet) {
                System.out.println(Arrays.toString(ints));
            }   //打印出set中所有的元素
        }
    }
    

    在这里插入图片描述

    • 从打印结果中我们可以看出,我们预期添加10个元素到TreeSet中,而10个元素的第一个值都不一样,如果是以hash值判断的话,这些元素都互不相同,而最终只有一个元素添加成功,这就说明其他元素都被当做重复元素处理了

    改写Comparator添加重复元素以及出现的问题

    • 通过以上分析,我们可以尝试通过修改Comparator,在其结果为0时,强制返回一个非零的数,来达到添加重复元素的目的
    TreeMap<Integer,String> tree = new TreeMap<Integer,String>(new Comparator<Integer>(){
                @Override
                public int compare(Integer o1, Integer o2) {
                    if(o1.equals(o2))
                        return 1;
                    else
                    return o1-o2;
                }
            });
    
    • 问题来了,比如我们在compare中重写,判断两个元素一样是,强制返回1,元素是存进去了,可是我们在调用get方法去拿出这个元素和其值时,就出问题了,拿到的永远是null,也就是找不到这个元素!不按常规出牌总是要付出代价的,为什么呢??查看底层代码,我们可以发现,get方法取元素同样是根据比较器来取,调用compare方法查找,直到查找到能让compare方法返回0的元素,就判断,这个元素就是我们要找的元素,就将它的值取出来,如果查完了也没有返回0,那么就认为集合中不存在这个键,返回null!

    • 虽然用这种方法可以将重复的元素储存进去,当时相应的问题也会出现,当我们想使用ceiling(E e)或floor(E e)方法获得大于等于e的最大值,或小于等于e的最小值的时候,由于相等时返回值被强制修改为非0的值,所以无法获得等于e的值。

    • 同样的道理,TreeSet其实就是通过TreeMap来实现的,那么其也响应的特性。(比如ceiling()和floor()等等)

    展开全文
  • 主要介绍了从源码的角度浅析HashMap、TreeMap元素的存储和获取元素的逻辑;从Map与Set之间的关系浅析常用的Set中元素的存储和判断是否重复的逻辑,需要的朋友可以参考下
  • TreeSet重复元素判断依靠Comparable接口直接完成。 TreeSet能够进行排序,实际上是对对象数组的排序,如果要对对象数组排序,对象所在的类需要继承Comparable接口并且覆写CompareTo()方法。 如果使用Comparable...
    1. TreeSet能够进行排序且是升序,实际上是对对象数组的排序,如果要对对象数组排序,对象所在的类需要继承Comparable接口并且覆写compareTo()方法。
    2. 覆写compareTo()方法的同时其实也是对重复元素的判断。
    3. 如果使用Comparable接口进行大小关系匹配,所有属性必须全部进行操作。
    4. compareTo()方法:
      本身就是当前对象,就是this;
      目标对象就是新插入的对象。

      int compareTo(Object o)
      结果 > 0:本身大于目标对象
      结果 < 0:本身小于目标对象
      结果 = 0:本身等于目标对象


    5. 总体理解:
      就是覆写compareTo()方法的时候,因为集合中的对象是排好序的,所以每当有一个目标对象准备放入到集合中,会先从已排好序的对象中线取出一个最大的对象,如果目标对象小的话,会一直往后比。每次比较的时候会对所有属性进行比较判断,如果所有属性都相等,则这个目标对象不会放入集合中,说明重复,然后判断大小关系,把当前对象放入到合适的位置。
    6. 使用方法
    package www.treeset;
    
    import java.util.Set;
    import java.util.TreeSet;
    import java.util.concurrent.Semaphore;
    
    class Person implements Comparable<Person>{
    
        private String name;
        private Integer age;
    
        public Person(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
     /*
        覆写compareTo()方法
        按照年龄排序,升序
        当前对象的年龄大的话返回1
        当前对象的年龄小的话返回-1
        当年龄相等的时候比较其他属性判断是否相等,如果返回1则俩对象相等。
         */
        @Override
        public int compareTo(Person o) {
            if (this.age > o.age){
                return 1;
            }else if (this.age < o.age){
                return -1;
            }else {
                return this.name.compareTo(o.name);
            }
        }
    }
    
    public class CompareToTest {
        public static void main(String[] args) {
            Set<Person> set = new TreeSet<>();
            set.add(new Person("alice",20));
            set.add(new Person("ls",19));
            set.add(new Person("alice",20));
            System.out.println(set);
        }
    }
    
    

    在这里插入图片描述

    展开全文
  • * 虽然TreeSet能实现重复元素判断,但它只适用于排序类操作的环境下,而其它子类需要消除重复元素该怎么做??比如hashSet,hashmap * 依靠Object类提供的两个方法hashcode和equals 假设equals和hashcode...
    ----测试类
    
    package TreeSetTest;
    
    import java.util.HashMap;
    import java.util.HashSet;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.Map.Entry;
    import java.util.Set;
    import java.util.TreeSet;
    
    
    public class TreeSetTest {
    	
    	
    	public static void main(String[] args) {
    		/*map循环输出*/
    		Map<String,Object> map = new HashMap<String,Object>();
    		map.put("1", "a");
    		map.put("2", "a");
    		Set<Entry<String, Object>> set = map.entrySet();//map中可以看做是多个map.entry的接口对象
    		System.out.println(set);//[3=a, 2=a, 1=a, 4=a]
    		Iterator<Entry<String, Object>>  it = set.iterator();//Collection实现了Iterable<T> 接口,故可以该接口提供的迭代方法
    		while (it.hasNext()) {
    			Entry<String, Object> entry = it.next();
    			System.out.println(entry.getKey() + "==" + entry.getValue());//再利用Map.Entry提供的方法,遍历,map主要用来查找,集合用来输出hash都是无序的
    		}
    		/*TreeSet 实现对象比较,必须实现Comparable接口,因为Integer和String类已经实现了该接口,所以如果泛型是基本类型和String类型则不需在实现该接口,自定义  排序和过滤重复的信息*/
    		Set<Student> setStu = new TreeSet<Student>();
    		setStu.add(new Student("胡明明","24"));
    		setStu.add(new Student("胡明明","24"));
    		setStu.add(new Student("胡明明1","25"));
    		setStu.add(new Student("肖体秀","23"));
    		System.out.println(setStu);
    		/**
    		 *  虽然TreeSet能实现重复元素的判断,但它只适用于排序类操作的环境下,而其它子类需要消除重复元素该怎么做??比如hashSet,hashmap
    		 *  依靠Object类提供的两个方法hashcode和equals  假设equals和hashcode返回的结果都一致则重复
    		 */
    		Set<Book> hashSet = new HashSet<Book>();
    		hashSet.add( new Book("java", 78));
    		hashSet.add( new Book("java", 78));
    		hashSet.add(new Book("php", 78));
    		System.out.println(hashSet);//[Book [titie=java, price=78], Book [titie=php, price=78]]
    		//为了确保map中key的唯一性,也可以重写equals和hashcode方法
    		Map<Book,Integer> mmp = new HashMap<Book, Integer>();
    		mmp.put( new Book("js", 78),1);
    		mmp.put( new Book("js", 78),1);
    		mmp.put(new Book("html", 78),1);
    		System.out.println(mmp);//{Book [titie=js, price=78]=1, Book [titie=html, price=78]=1}
    	}
    	 
    }
    
    ----学生类
    
    package TreeSetTest;
    
    public class Student implements Comparable<Student>{
    		private String name;
    		private String age;
    		
    		public Student(String name, String age) {
    			super();
    			this.name = name;
    			this.age = age;
    		}
    		public String getName() {
    			return name;
    		}
    		public void setName(String name) {
    			this.name = name;
    		}
    		public String getAge() {
    			return age;
    		}
    		public void setAge(String age) {
    			this.age = age;
    		}
    		@Override
    		//备注:比较对象时TreeSet<Objetc>,假设类中存了5个属性,但是我们只比较了3个,并且这3个属性还相同,则TreeSet会认为这个对象也相同,从而会新的替换旧的(有序),造成数据遗失
    		public int compareTo(Student o) {
    			//如何比较自己自定义吧,我这里就暂时认定为假设名字相同和年龄相同则认为元素重复,在比较年龄,按大小排序
    			if(this.age.equals(o.age) && this.name.equals(o.name)){
    				return 0;
    			}else if(Integer.parseInt(this.age )>=Integer.parseInt(o.age)){
    				return 1;
    			}else{
    				return -1;
    			}
    		}
    		@Override
    		public String toString() {
    			return name +":" + age;
    		}
    		
    	
    }
    
    ----Book类
    
    
    package TreeSetTest;
    
    public class Book {
    	private String titie;
    	private int price;
    
    	public Book(String titie, int price) {
    		super();
    		this.titie = titie;
    		this.price = price;
    	}
    	public String getTitie() {
    		return titie;
    	}
    	public void setTitie(String titie) {
    		this.titie = titie;
    	}
    	public int getPrice() {
    		return price;
    	}
    	public void setPrice(int price) {
    		this.price = price;
    	}
    	@Override
    	public String toString() {
    		return "Book [titie=" + titie + ", price=" + price + "]";
    	}
    	@Override
    	public int hashCode() {
    		final int prime = 31;
    		int result = 1;
    		result = prime * result + price;
    		result = prime * result + ((titie == null) ? 0 : titie.hashCode());
    		return result;
    	}
    	@Override
    	public boolean equals(Object obj) {
    		if (this == obj)
    			return true;
    		if (obj == null)
    			return false;
    		if (getClass() != obj.getClass())
    			return false;
    		Book other = (Book) obj;
    		if (price != other.price)
    			return false;
    		if (titie == null) {
    			if (other.titie != null)
    				return false;
    		} else if (!titie.equals(other.titie))
    			return false;
    		return true;
    	}
    	
    }
    
    

     

    展开全文
  • 解析HashMap、HashSet、TreeMap、TreeSet判断元素是否存在的逻辑。
  • 引言 大家都应该了解许多存储...不能添加重复元素,添加顺序和打印顺序不一致,但在容器内部是有特定的规则进行排序的。 TreeSet容器对象:添加一种类型之后不能再添加其他类型(HashSet是不是也是这样呢?) 重...
  • java TreeSet是如何添加不重复元素

    千次阅读 2018-07-11 19:53:20
    java TreeSet是如何添加不重复元素的 compare()方法很重要。
  • 目录Set集合保证元素重复的原理&Java中的排序接口1. Set体系集合的继承关系和特点2. HashSet如何保证元素的唯一性2.1 HashSet集合的简介和HashSet#add()方法2.2 重写hashCode()方法的原则2.3 重写equals()方法...
  • 继上篇博客继续TreeSet排序分析重复元素判断集合输出迭代输出:Iterator双向迭代接口:ListIterator枚举输出: Enumerationforeach输出 TreeSet排序分析 要想进行排序实际上是针对于对象数组进行的排序处理,而...
  • 因此要判断元素是否相同其实就是判断两个对象是否相同。但是由于我们定义不同,所要判断的依据也就不同。 什么是判断依据呢? 可以是两个对象的地址,名称,年龄,等等。 一、ArrayList ArrayList中判断元素相同是...
  • Set为无序集合(无序是指存入元素的先后顺序与输出元素的先后顺序不一致),不允许添加重复元素。Set是个接口,不能直接实例化对象,即 Set s=new Set()是错误的 。 Set的实现类常用的有:HashSet和TreeSet。 1....
  • TreeSet存储自定义对象 TreeSet存储自定义对象需要做哪些改动 我们知道,在HashSet里面存储自定义对象时要重写HashCode()和equals()方法。同样的在TreeSet里面存储自定义对象时也要做一些改动。 以自定义比较器为例 ...
  • Set是一种数据集合。...与List不同的是,Set中的元素是无无需的,并且都以某种规则保证存入的元素不会出现重复。 它的特点也就是: 1. 元素不会出现重复。 2. 元素是无序的。(存取无序) 3....
  • hashSet与TreeSet判断重复问题 底层原理: hashSet的数据存储是哈希表, TreeSet的数据存储是红黑树 所以hashSet存储数据时,元素不比较,只需要去重即可 1.先看元素的地址是否相同 分别调用hashCode() 2....
  • HashSet 的实现其实非常简单,它只是封装了一个 HashMap 对象来存储所有的集合元素,所有放入 HashSet 中的集合元素实际上由 HashMap 的 key 来保存,而 HashMap 的 value 则存储了一个 PRESENT,它是一个静态的 ...
  • Map里面存放的每一个元素都是key-value这样的键值对,而且都是通过put方法进行添加的,而且相同的key在Map中只会有一个与之关联的value存在。put方法在Map中的定义如下。  V put(K key, V value);  它用来存放...
  • 使用TreeSet去除字符串数组里的重复元素
  • TreeSet添加自定义元素(比较)

    千次阅读 2017-08-19 09:37:10
    TreeSet集合中添加元素的时候,如果元素本身具备了自然顺序的特征,那么就按照自然排序的顺序添加  2. 添加自定义元素,这些元素没有一个自然顺序,这里添加不进入,我们就可以来提供一个当前类的一种比较规则 ...
  • /** * @author :肖佳嘉 * @Date:2019-04-05 */ package ... import java.util.ArrayList; import java.util.Comparator;...import java.util.TreeSet; public class Case8_pratise { public stat...
  • 基于TreeMap实现的支持可重复元素TreeSet github地址,欢迎star 为什么要开发这个数据结构 搞过java的人应该都知道TreeSet,但是TreeSet是不支持重复元素的。有人会说,那用ArrayList或LinkedList不就可以了吗? ...
  • List<MyDto>... //去除规格值重复的数据 if (CollectionUtils.isNotEmpty(list)) { //设置比较属性 TreeSet<MyDto> set = new TreeSet<>(comparing(MyDto::getId)); ...
  • 跟汤老师学Java笔记:TreeSet如何对元素排序的依据是什么? 完成:第一遍 ...当添加的两个元素的compareTo()的返回值为0时,则认为是相同元素,Set集合不可重复元素,会舍弃重复的元素 package season13;
  • Set集合如何判断重复元素

    千次阅读 2019-04-20 15:06:00
    1.TreeSet子类是利用Comparable接口来实现重复元素判断,但是Set集合的整体特征就是不允许保存重复元素。 2.HashSet判断元素重复是利用Object类中的方法实现的: -|对象编码:public int hashCode(); -|对象....
  • HashSet区分重复元素: 先使用hashcode方法判断已经存在HashSet中元素的hashcode值和将要加入元素hashcode值是否相同。如果不同,直接添加;如果相同,再调用equals方法判断,如果返回true表示HashSet中已经添加该...
  • 判断一个数组是否有重复元素

    千次阅读 2018-06-25 20:29:52
    数组长度为n,数的范围{0,n-1};数组元素随机排放,可能有重复值,怎样判断是否有重复元素?下面说明一下思路,这个问题各种办法都可以解决,但是算法的复杂度和性能上却各不相同,最笨的办法就是逐个比较。 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 46,543
精华内容 18,617
关键字:

treeset如何判断重复元素的