集合 判断是否为同一元素

总结:
  • 对于List集合,仅仅是通过判断两个对象的【equals】方法是否为true
  • 对于Hash系列的集合,是先判断对象的【hashCode】返回值是否相同,再判断对象的【equals】返回值是否为true
  • 对于Tree 系列的集合,是判断两个对象的【compareTo】方法的返回结果是否是0
  • 注意【Object】中的equals方法等同于==;默认不同对象调用hashCode方法返回的都是不同的整数。
  • 注意【String】类重写了hashCode【和】equals方法,内容相同则两个值也相同
  • package com.anzhi.heifer.commons.utils;
    
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.Comparator;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    import java.util.TreeSet;
    
    @SuppressWarnings("all")
    public class SetDemo {
    
    	public static void main(String[] args) {
    		// 对于ArrayList集合,判断是否是同一对象,仅仅通过调用对象的【equals】方法
    		ArrayList<Person> al = new ArrayList<Person>();
    		al.add( new Person( "lisi", 20 ) );
    		al.add( new Person( "bqt", 21 ) );
    		al.add( new Person( "hello", 22 ) );
    		System.out.println( al );//[Person [name=lisi, age=20], Person [name=bqt, age=21], Person [name=hello, age=22]]
    		Person person = new Person( "lisi", 23 );
    		System.out.println( al.contains( person ) );// true,contains判断时调用的也是Person的equals方法
    		al.add( person );// 允许元素重复
    		al.add( person );// 允许元素重复
    		System.out.println( al );//[Person [name=lisi, age=20], Person [name=bqt, age=21], Person [name=hello, age=22], Person [name=lisi, age=23], Person [name=lisi, age=23]]
    		System.out.println( "***************************" );
    		System.out.println( getSingleElement( al ) );// [Person [name=lisi, age=20], Person [name=bqt, age=21], Person [name=hello, age=22], Person [name=lisi, age=23]]
    		Collections.sort( al, new ComparatorByName() );// 按指定的比较器排序
    		System.out.println( al );// [bqt,21, hello,22, lisi,20, lisi,23]
    		Collections.sort( al );// 以对象自己的排序规则排序
    		System.out.println( al );// [lisi,20, bqt,21, hello,22, lisi,23]
    
    		// 对于TreeSet,是根据【比较方法】的返回结果是否是0,是0,就是相同元素。注意:优先使用的是Set指定的比较器。
    		TreeSet<String> ts = new TreeSet<String>( new ComparatorByLength() );
    		ts.add( "aaa" );
    		ts.add( "z" );
    		ts.add( "ca" );
    		ts.add( "ac" );
    		ts.add( "aaa" );// 重复的元素,不允许
    		System.out.println( ts );// [z, ac, ca,  aaa],按字符串长度由短到长排序,如果长度相同,则按字符串自己的规则排序(自然排序)
    		
    		TreeSet<Person> ts2 = new TreeSet<Person>( new ComparatorByName() );
    		// TreeSet<Person> ts2 = new TreeSet<Person>();
    		ts2.add( new Person( "aaa", 21 ) );
    		ts2.add( new Person( "nbaq", 21 ) );
    		ts2.add( new Person( "ca", 21 ) );
    		ts2.add( new Person( "ac", 21 ) );
    		ts2.add( new Person( "aaa", 22 ) );// 按名字(字符串)自己的规则排序,若名字相同按年龄由小到大排序
    		ts2.add( new Person( "aaa", 21 ) );// 重复的元素,不允许
    		System.out.println( ts2 );// [aaa,21, aaa,22, ac,21, ca,21,  nbaq,21]。若不指定比较器,结果为[aaa,21, aaa,22]
    
    		// 对于Hash系列的集合,是调用Key的 equals【和】hashCode方法
    		Map<Person, Integer> map = new HashMap<Person, Integer>();
    		map.put( new Person( "ca", 21 ), 1 );
    		map.put( new Person( "ca", 23 ), 3 );// equals相同,但hashCode不同,当做不同的对象
    		map.put( new Person( "aaa", 22 ), 2 );
    		map.put( new Person( "z", 26 ), 4 );
    		System.out.println( map.put( new Person( "ac", 400 ), 5 ) );// null
    		System.out.println( map.put( new Person( "ac", 500 ), 6 ) );// 5。equals和hashCode都相同,当做同一Key,把之前的【Value】替换掉,注意【Key】并没有变!
    		for (Person key : map.keySet()) {
    			Integer value = map.get( key );
    			System.out.print( "【" + key.toString() + "-" + value + "】" );// 【aaa,22-2】【ac,400-6】【ca,23-3】【z,26-4】【ca,21-1】
    		}
    
    	}
    
    	// 去除ArrayList中的重复元素
    	public static <T> ArrayList<T> getSingleElement(ArrayList<T> al) {
    		ArrayList<T> temp = new ArrayList<T>();
    		Iterator<T> it = al.iterator();
    		while (it.hasNext()) {
    			T obj = it.next();
    			// 判断被迭代到的元素是否在临时容器存在
    			if (!temp.contains( obj ))
    				temp.add( obj );
    		}
    		return temp;
    	}
    
    	// 按字符串长度排序
    	public static class ComparatorByLength implements Comparator<String> {
    		public int compare(String s1, String s2) {
    			int temp = s1.length() - s2.length();
    			return temp == 0 ? s1.compareTo( s2 ) : temp;// 按字符串长度由短到长排序,如果长度相同,则按字符串自己的规则排序(自然排序)
    		}
    	}
    
    	// 按Person名字排序
    	public static class ComparatorByName implements Comparator<Person> {
    		public int compare(Person p1, Person p2) {
    			int temp = p1.name.compareTo( p2.name );//如果参数字符串等于此字符串,则返回值 0;如果此字符串按字典顺序小于字符串参数,则返回一个小于 0 的值;如果此字符串按字典顺序大于字符串参数,则返回一个大于 0 的值
    			return temp == 0 ? p1.age - p2.age : temp;// 按名字(字符串)自己的规则排序,若名字相同按年龄由小到大排序
    		}
    	}
    
    	public static class Person implements Comparable<Person> {
    		// Comparable接口强行对实现它的每个类的对象进行整体排序。这种排序被称为类的自然排序,类的 compareTo
    		// 方法被称为它的自然比较方法
    		public String name;
    		public int age;
    
    		public Person(String name, int age) {
    			this.name = name;
    			this.age = age;
    		}
    
    		public int compareTo(Person p) {
    			return this.age - p.age;// 按年龄由小到大排序
    		}
    
    		public int hashCode() {
    			int newAge = this.age;
    			if (age > 150)
    				newAge = 150;
    			return name.hashCode() + newAge;// 这里的hashCode是基于String类的hashCode更改的
    		}
    
    		public boolean equals(Object obj) {
    			if (this == obj)
    				return true;
    			if (!(obj instanceof Person))
    				return false;
    			Person p = (Person) obj;
    			return this.name.equals( p.name )&&this.age==p.age;// 注意:是【先】判断hashCode是否相同,【再】判断equals是否为true
    		}
    
    		@Override
    		public String toString() {
    			// 默认返回值是【person.getClass().getName() + '@' +
    			// Integer.toHexString(person.hashCode())】
    			return name + "," + age;
    		}
    		
    	}
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值