SET集合、MAP集合总结

3 篇文章 0 订阅
2 篇文章 0 订阅

Set接口

set接口常用方法

方法名描述
add(E e)确保此 collection 包含指定的元素(可选操作)。
addAll(Collection<? extends E> c)将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。
clear()移除此 collection 中的所有元素(可选操作)。
contains(Object o)如果此 collection 包含指定的元素,则返回true。
containsAll(Collection<?> c)如果此 collection 包含指定 collection 中的所有元素,则返回 true。
equals(Object o)比较此 collection 与指定对象是否相等。
isEmpty()如果此 collection 不包含元素,则返回true。
iterator()返回在此 collection 的元素上进行迭代的迭代器。
remove(Object o)从此 collection 中移除指定元素的单个实例,如果存在的话(可选操作)。
removeAll(Collection<?> c)移除此 collection 中那些也包含在指定 collection 中的所有元素(可选操作)。
retainAll(Collection<?> c)仅保留此 collection 中那些也包含在指定 collection 的元素(可选操作)。
size()返回此 collection 中的元素数。
toArray()返回包含此 collection 中所有元素的数组。

存储特点

相对无序存储,不可以存储相同的元素(排重),不能通过下标访问

HashSet集合特点

此类实现Set接口,由哈希表(实际上是一个HashMap实例)支持。它不保证set的迭代顺序;特别是它不保证该顺序恒久不变。此类允许使用null元素。

Hash:哈希——实际含义散列,就是一种算法,把任意长度的输入通过散列算法变换成固定长度的输出,该输出就是散列值。

哈希表:数组加链表,既有数组的优点也有链表的优点。

存储特点:相对无序存储,不可以存储相同元素(排重),通过哈希表实现的集合。

	  public static void main(String[] args) {
		//创建对象
		Set<String> set=new HashSet<String>();
		//1添加
		set.add("菊花");
		set.add("枸杞");
		set.add("红枣");
		set.add("人参");
		set.add("灵芝");
		set.add("枸杞");
		System.out.println("元素个数:"+set.size());
		System.out.println(set);
		//2删除
		//2.1删除一个
//		set.remove("灵芝");
//		System.out.println("删除之后:"+set);
//		//2.2清空
//		set.clear();
		//3遍历
		//3.1foreach
		System.out.println("--------增强for----------");
		for (String string : set) {
			System.out.println(string);
		}
		//3.2使用迭代器
		System.out.println("---------迭代器-------");
		Iterator<String> it=set.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
		//4判断
		System.out.println(set.contains("菊花"));
		System.out.println(set.contains("梅花"));
	}
}

运行结果:
在这里插入图片描述
从运行结果可以看出HashSet集合与插入顺序无关,无序存储。

HashSet集合实现排重

HashSet的重复依据: hashCode和equals
需要同时重写hashCode和equals方法,实现排重。单写任何一个都无法实现排重的效果

hashCode()是Object中的方法,每个对象的hashCode值是唯一的,所以可以理解成hashCode值表示这个对象在内存中的位置。字符串String的hashCode(),是根据内容计算的。HashSet集合排重时,需要判断两个对象是否相同,对象相同的判断可以通过hashCode值判断,所以需要重写hashCode()方法
equals()方法是Object类中的方法,表示比较两个对象是否相等,若不重写相当于比较对象的地址。

代码实现:

案例:设计一个Student类,同时重写hashCode和equals方法,检查是否实现排重

	private String name;
	public Student(String name) {
		super();
		this.name = name;
	}
	public Student() {
		super();
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		return "Student [name=" + name + "]";
	}
	@Override
  	//重写equals
	public boolean equals(Object obj) {
      	//先判断传入的参数对象是否是Student对象,若不是直接返回false
		if(obj instanceof Student) {
          	//若是,强转成Student对象,并比较属性的值
			Student s = (Student) obj;
			if(this.name.equals(s.name)) {
              	 //若属性的值相同,则返回true
				return true;
			}
		}
		return false;
	}
  	@Override
    public int hashCode(){
      	/*hashCode方法返回值是int类型,所以重写时需要找到int类型的数据返回,还要保证此方法的返回值与对象的所有属性都相关,所以返回姓名属性的字符串的长度*/
		return this.name.hashCode();
    }
}
LinkedHashSet集合

LinkedHashSet类是具有可预知迭代顺序(相对有序)的Set接口的哈希表和链接列表实现。是HashSet的子类。

存储特点:
有序存储,不可以存储相同元素(排重),通过链表实现的集合的有序。
LinkedHashSet集合的元素排重与HashSet集合排重方法一致。

TreeSet集合

TreeSet集合是可以给元素进行重新排序的一个Set接口的实现。使用元素的自然顺序对元素进行排序,或者根据创建 set 时提供的Comparator进行排序,具体取决于使用的构造方法。
存储特点:
无序存储,排重,通过红黑树实现的集合,可以给元素进行重新排序

TreeSet集合的元素排序

自然排序

元素所属的类需要实现java.lang.Comparable接口,并重写compareTo方法。
compareTo方法除了可以进行排序外,还有排重的功能,但是必须在compareTo方法中对类中所有的属性值都进行判断,否则不比较那个属性,排重就会忽略哪个属性

  • 案例:设计一个Person类,实现将Person对象添加到TreeSet集合中时,对所有的元素进行排序。
	private String name;
	private int age;
	public Person() {
		super();
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
  	//重写compareTo方法,按照年龄升序,若年龄相同按照姓名降序排序
	public int compareTo(Person o) {
      	//Person中有两个属性,此方法中必须对name和age两个属性都进行比较,否则将无法正确排重
		if(this.age != o.age) {
			return this.age - o.age;
		}else {
			return o.name.compareTo(this.name);
		}
	}
}

定制排序

  • 元素需要通过java.util.Comparator接口(比较器)中的compare方法进行比较大小,并排序。

  • compare方法除了可以进行排序外,还有排重的功能,但是必须在compare方法中对类中所有的属性值都进行判断,否则不比较那个属性,排重就会忽略哪个属性

  • TreeSet集合中的无参数构造方法默认使用自然排序的方式对元素进行排序,使用TreeSet集合的定制排序时,创建集合对象不可以直接使用无参数构造方法,需要使用传入一个Comparator比较器的构造方法创建集合对象。

代码实现:

	private String name;
	private int age;
	@Override
	public String toString() {
		return "Animal [name=" + name + ", age=" + age + "]";
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public Animal(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public Animal() {
		super();
	}
}
public class AnimalDemo{
    public static void main(String[]args){
      	//创建一个TreeSet集合,使用Comparator接口的匿名内部类的匿名对象作为比较器
        TreeSet<Animal> treeSet = new TreeSet<>(new Comparator() {
          	@Override
            public int compare(Animal o1, Animal o2) {
                if(o1.age!=o2.age) {
                    return o2.age - o1.age;
                }else {
                    return o1.name.compareTo(o2.name);
                }
            }
        });
      	//添加元素
      	treeSet.add(new Animal("大黄", 1));
      	treeSet.add(new Animal("旺财", 2));
      	//遍历集合
      	Iterator<Animal> it = treeSet.iterator();
        while(it.hasNext()){
          	System.out.println(it.next());
        }
    }
}

Map接口

Map接口是将键映射到值的对象。一个映射不能包含重复的键,每个键最多只能映射到一个值,值可以重复。
cn—>中国
usa—>美国
uk—>英国
us—>美国
cn—>中华人民共和国

Map接口的常用方法
方法名描述
clear()从此映射中移除所有映射关系(可选操作)。
containsKey(Object key)如果此映射包含指定键的映射关系,则返回 true。
containsValue(Object value)如果此映射将一个或多个键映射到指定值,则返回 true。
entrySet()返回此映射中包含的映射关系的 Set集合。
equals(Object o)比较指定的对象与此映射是否相等。
get(Object key)返回指定键所映射的值;如果此映射不包含该键的映射关系,则返回 null。
hashCode()返回此映射的哈希码值。
isEmpty()如果此映射未包含键-值映射关系,则返回 true。
keySet()返回此映射中包含的键的 Set 集合。
put(K key, V value)将指定的值与此映射中的指定键关联(可选操作)。
putAll(Map<? extends K,? extends V> m)从指定映射中将所有映射关系复制到此映射中(可选操作)。
remove(Object key)如果存在一个键的映射关系,则将其从此映射中移除(可选操作)。
size()返回此映射中的键-值映射关系数。
Map常用实现类
HashMap
  • 基于哈希表的Map接口的实现。此实现提供所有可选的映射操作,并允许使用null值和null键。此类不保证映射的顺序。

  • 存储特点:
    相对无序存储,元素以键值对形式存在,键不可以重复,值可以重复,元素整体排重,可以快速的通过键查找到所对应的值,通过哈希表实现的集合。

  • HashMap集合的排重,只需要重写键所属的类的hashCode和equals方法即可。

代码实现:

public class Person {
	private String name;
	private int age;
	public Person() {
		super();
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	@Override
	public int hashCode() {
		return age + name.length();
	}
	@Override
	public boolean equals(Object obj) {
		if(obj instanceof Person) {
			Person p = (Person) obj;
			if(p.name.equals(name)&&p.age==age) {
				return true;
			}
		}
		return false;
	}
}
//Dog类作为值
public class Dog {
	private String name;
	public Dog(String name) {
		super();
		this.name = name;
	}
	public Dog() {
		super();
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	@Override
	public String toString() {
		return "Dog [name=" + name + "]";
	}
}
//测试类
public class Demo {
	public static void main(String[] args) {
		HashMap<Person, Dog> map = new HashMap<>();
		map.put(new Person("zhangsan", 12), new Dog("大黄"));
		map.put(new Person("lisi", 12), new Dog("旺财"));
		map.put(new Person("zhangsan", 12), new Dog("二哈"));
      
	}
}

map集合中若向集合中添加相同键的键值对时,新的值会将旧的值覆盖。
上述代码中map集合中有两个键值对,分别为:张三-12—二哈,lisi-12—旺财

LinkedHashMap
  • LinkedHashMap集合是具有可预知迭代顺序的Set接口的哈希表和链接列表实现。此实现与HashSet的不同之外在于,后者维护着一个运行于所有条目的双重链接列表。用法与HashSet类似。
  • 存储特点:
    有序存储,元素排重,通过链表实现的集合。
Hashtable
  • 此类实现一个哈希表,该哈希表将键映射到相应的值。任何非null对象都可以用作键或值。Hashtable有一个子类Properties,Properties集合使用的比较频繁。
  • 存储特点:
    相对无序存储,元素排重,通过哈希表实现的集合。
HashMap和Hashtable的区别

1)Hashtable线程安全的,而HashMap线程不安全的
2)Hashtable中不允许存在null的键和null值,但是HashMap中允许null的键和null值

Map集合的遍历

使用keySet方法与get方法结合

    public static void main(String[] args){
      	HashMap<String, Integer> map = new HashMap<>();
      	map.put("aaa", 12);
      	map.put("bbb", 13);
      	map.put("ccc", 14);
      	//通过keySet获取map中所有键
      	Set<String> set = map.keySet();
      	//获取set的迭代器
      	Iterator<String> it = set.iterator();
        while(it.hasNext()){
          	String s = it.next();
          	//通过迭代的键,找到对应的值,一起输出
          	System.out.println(s+"---"+map.get(s));
        }
    }
}
使用Map.Entry方法

调用Map集合的entrySet方法,相当于将Map集合转成一个Set集合,再通过Set集合的遍历方式遍历即可。

	public static void main(String[] args) {
		HashMap<String, Integer> map = new HashMap<>();
		map.put("aaa", 111);
		map.put("bbb", 222);
		map.put("ccc", 333);
		//将map转成一个Set集合
		Set<Map.Entry<String, Integer>> set = map.entrySet();
		//遍历set
		Iterator<Map.Entry<String, Integer>> it = set.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
	}
}
TreeMap

存储结构:自平衡红黑二叉树(具体大家可以自行查询红黑树)
特点:
1 存储键值对、键不能重复、一个键对应一个值、值可以重复
2 无序,数据会进行排序。
排重依据:Comparable接口的compareTo()方法的返回值。如果返回0就认为是重复的元素。


- TreeMap的使用

- 存储结构:自平衡红黑二叉树

- @author wgy
  *
   */
  public class Demo5 {
  public static void main(String[] args) {
  	//创建集合
  	TreeMap<Person, String> treeMap=new TreeMap<>();
  	Person p1=new Person("马云", 50);
  	Person p2=new Person("李彦宏", 45);
  	Person p3=new Person("马化腾", 40);
  	Person p4=new Person("马云", 50);
  	
  	//1添加数据
  	treeMap.put(p1, "杭州");
  	treeMap.put(p2, "北京");
  	treeMap.put(p3, "深圳");
  	treeMap.put(p4, "shanghai");
  	
  	System.out.println("元素个数:"+treeMap.size());
  	System.out.println(treeMap.toString());
  	
  	System.out.println("---------------------比较器--------------------");
  	TreeMap<Person, String> treeMap2=new TreeMap<>(new Comparator<Person>() {

  ​		@Override
  ​		public int compare(Person o1, Person o2) {
  ​			int n=o1.getAge()-o2.getAge();
  ​			int n2=o1.getName().compareTo(o2.getName());
  ​			return n==0?n2:n;
  ​			
  ​		}
  ​	});
  ​	treeMap2.put(p1, "杭州");
  ​	treeMap2.put(p2, "北京");
  ​	treeMap2.put(p3, "深圳");
  ​	treeMap2.put(p4, "shanghai");
  ​	
  ​	System.out.println(treeMap2.toString());
  ​	
  }
  }

关于Set和Map总结就到次为止,初写博客,可能在一些地方存有不足之处,欢迎各位大佬指点、批评,也欢迎像我一样的java初学者交流,共同进步。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值