Java集合Set

Java集合汇总开始看起吧,重父类的Collection讲起。

1.2:Set接口
    无序的,不可重复,允许null值。
    无序性:指的是元素底层存储的位置是无序的。不是打印出来的值的顺序。
    不可重复性:当向Set中添加重复值的时候,后面的值添加不进去。
    要求:往set中添加的元素,其所在类一定要重写equals() 和 hashCode() 方法,进而保证Set中元素的无序性和不可从重复性。
    Set中的元素如何存储?使用了哈希算法。
     * 向Set中添加对象时,首先调用此对象所在类的hashCode() 方法,计算此对象的哈希值,此哈希值决定了对象在Set中存储的位置。
     * 如若此位置之前没有对象存储,则这个对象直接存储到此位置。
     * 如果此位置已有对象储存,再通过equals() 比较这两个对象是否相同,如果相同,后一个对象就不添加进来。
     * 要求:hashCode() 方法,和equals()方法一致,意思如下:
     * 如果两个元素计算出来的 hashCode()返回值不一样,则equals()结果也要不一样
     * 如果两个元素计算出来的 hashCode()返回值一样,则equals()结果也要一样
     三个实现类HashSet,LinkedHashSet,TreeSet
1.2.1 HashSet类介绍

@Test
		public void testHashSet() {
			Set set = new HashSet();
			set.add(123);
			set.add(456);
			set.add("张三");
			set.add(new String("张三"));
			set.add(null);
			set.add(951);
			set.add(new Person("小王", 15));
			set.add(new Person("小李", 14));
			// 如果不重写person中的equals()方法,和hashCode()方法,下面new的Person依旧可以添加进Set。
			set.add(new Person("小李", 14));

			Iterator iterator = set.iterator();
			while (iterator.hasNext()) {
				System.out.println(iterator.next());
			}
		}

1.2.2 LinkedHashSet
     LinkedHashSet是HashSet子类,同时也实现了 Set接口。
     * LinkedHashSet:使用链表维护了元素添加进集合的添加顺序。
     * LinkedHashSet 根据元素的hashCode值来决定元素的存储位置,
     * 但同时使用链表维护元素的次序,这使得元素看起来是插入顺序保存的。
     * 导致我们遍历LinkedHashSet集合元素时,是按照添加顺序遍历的。
     * 元素存储的是无序的,只是用链表连接起来了,显的有序。
     *
     * LinkedHashSet插入性能略低于 HashSet( 因为要维护链表 )
     * 但是迭代访问Set中全部元素性能较好( 也因为有链表存在 )
    *
    * LinkedHashSet 不允许集合元素重复。

@Test
		public void TestLinkedHashSet() {
			Set set = new LinkedHashSet();
			set.add(985);
			set.add(211);
			set.add(211);
			set.add("张三");
			set.add(new Person("老王", 17));

			Iterator iterator = set.iterator();
			while (iterator.hasNext()) {
				System.out.println(iterator.next());
			}
		}

1.2.3 TreeSet
    * TreeSet
     * 1.只能添加同类型元素
     * 2.相同元素不会重复添加
     * 3.添加进集合的元素,可以人为指定顺序进行遍历,像String,包装类等,默认按照从小到大的顺序遍历
     * 4.向TreeSet中添加自定义对象时,有两种排序方法:自然排序 和 定制排序
     * 5.向TreeSet中添加元素时,首先按照compareTo()进行比较,一旦返回0,表示两元素相同。
     * 也许仅是两个对象的此属性相同(可能此对象有多个属性),但程序会认为这两个对象相同,进而后一个对象不能添加进来。
     *
     * CompareTo() 与 hashCode() 以及 equals() 三者保持一致。
     *
     * 自然排序和定制排序的选择:
     * 举例:如果要把Person类add到TreeSet中,但是Person类你无法修改(比如你没权限动这个类),就选择定制排序,如果你可以操作Person类,则可以选自然排序。
     * 定制排序优先级较高,如果同时写了自然排序和定制排序,最终按照自然排序实现。

			/**
			 * String,包装类等得默认排序
			 */
			@Test
			public void testTreeSet() {
				Set set = new TreeSet();
				set.add("BB");
				// 之前添加的是String,这里再添加int就会报错。
				// set.add(123);
				set.add("GG");
				set.add("ZZ");
				set.add("YY");
				set.add("AA");
				set.add("AA");

				for (Object o : set) {
					System.out.println(o);
				}
			}

			/**
			 * 自然排序
			 * 然排序:要求自定义类实现java.long.Comparable接口,并重写其compareTo(Object obj)方法,意在指明按照哪个属性排序
			 */
			@Test
			public void testTreeSet1() {
				Set set = new TreeSet();
				// 如果Person类没有实现Comparable接口时,向TreeSet中添加Person对象时,报类转换异常:java.lang.ClassCastException
				set.add(new Person("AA", 12));
				set.add(new Person("GG", 17));
				set.add(new Person("BB", 10));
				set.add(new Person("XX", 9));
				set.add(new Person("XX", 10));

				for (Object o : set) {
					System.out.println(o);
				}
			}

			/**
			 * 定制排序
			 */
			@Test
			public void testTreeSet2() {

				Comparator com = new Comparator() {
					// 1. 向TreeSet中添加Customer类对象,再此compare()方法中,指明按照Custumer哪个属性排序
					@Override
					public int compare(Object o1, Object o2) {
						if (o1 instanceof Customer && o2 instanceof Customer) {
							Customer c1 = (Customer) o1;
							Customer c2 = (Customer) o2;
							// 单独根据id排序
							// return c1.getId().compareTo(c2.getId());
							// 为了让CompareTo() 与 hashCode() 以及 equals() 三者保持一致。
							int i = c1.getId().compareTo(c2.getId());
							if (i == 0) {
								return c1.getName().compareTo(c2.getName());
							}
						}
						return 0;
					}
				};
				// 2.将此对象作为形参,传递给TreeSet的构造器
				TreeSet set = new TreeSet(com);
				// 3.向TreeSet中添加对象【必须是Comparator接口中Compare方法中设计的类对象】
				set.add(new Customer(15, "AA"));
				set.add(new Customer(14, "DD"));
				set.add(new Customer(13, "BB"));
				set.add(new Customer(5, "XX"));

				for (Object o : set) {
					System.out.println(o);
				}

				// 每次往TreeSet中添加对象时,都是自动去找Comparator接口实现类的compare方法,进行比较排序。
			}
		```
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值