Java新人之路 -- 集合(下)

1.3 Set接口

Set集合 作为Collection另一子类,是一种不允许重复但不保证输出顺序的集合

子类一:HashSet()

HashSet 底层是通过HashMap实现的,HashMap的底层是哈希表结构

语法实例

public static void method() {
		Set set = new HashSet();
		set.add("东北平原");
		set.add("华北平原");
		set.add("长江中下游平原");
		set.add("关中平原");
		set.add("华北平原");
		System.out.println(set);
}

Collection的其他常用方法同样可以在Set中使用,不做演示

关于set集合如何实现不重复,参见我的这篇博客

子类二:TreeSet()

TreeSet 底层是TreeMap来实现的,TreeMap的底层是红黑树数据结构

二叉树:小的在左边,大的在右边

TreeSet对于基本数据包装类和字符串采取的默认的自然排序法

public static void method() {
	Set set = new TreeSet();
	set.add(14);
	set.add(7);
	set.add(27);
	set.add(44);
	System.out.println(set);//[7, 14, 27, 44]


	Set set2 = new TreeSet();
	set2.add("abc");
	set2.add("bdd");	
	set2.add("caa");
	set2.add("acc");
	System.out.println(set2);//[abc, acc, bdd, caa]
}

对于引用数据类型,没法直接排,对象里的属性不能作为直接的排序的依据

所以我们

  • 需要实现Comparable接口,然后重写compareTo方法,用于用户自定义排序方式
public static void objMethod() {
		Set set = new TreeSet();//里面的默认构造器是自然排序法,我们将自定义的放进去
		set.add(new User(17,"小李"));
		set.add(new User(23,"小张"));
		set.add(new User(15,"小孙"));
		set.add(new User(23,"小陈"));
		System.out.println(set);
}


class User implements Comparable{ //实现Comparable接口

	private int age;

	private String name;

	public User() {
	}

	public User(int age, String name) {
		super();
		this.age = age;
		this.name = name;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "User [age=" + age + ", name=" + name + "]";
	}
 
 /**
    * 用于用户自定义排序方式
    * 拿两个对象的年龄进行比较
    * >排左边 <排右边 0相等
    */
	@Override
	public int compareTo(Object obj) {
		User user = (User)obj; //进行类型转换 
		int temp=this.age - user.age;
		if(temp==0) {//先比较年龄,再比较名字,如果不等于0,直接返回结果
			//比较名字
			 return this.name.compareTo(user.name);
		}
		return temp;		
}

输出结果
[User [age=15, name=小孙], User [age=17, name=小李], User [age=23, name=小张], User [age=23, name=小陈]]
  • 但是Comparable的坏处是,没法定义多个compareTo方法以适应不同的比较规则
  • 这个时候我们用到了 Comparator 接口
  • TreeSet(Comparator<? super E> comparator) 构造一个新的,空的树集,根据指定的比较器进行排序。
/**
	 * 比较器实例
	 * 实体类来自Item,比较器来自CompareByPriceAndBrand
	 * 
	 */
	public static void customObjMethod() {
		Set set = new TreeSet(new CompareByPriceAndBrand());
		//里面的默认构造器是自然排序法,我们将自定义的放进去
		set.add(new Item(9.9,"锅巴","bbc"));
		set.add(new Item(24.8,"夏威夷果","三只松鼠"));
		set.add(new Item(18.9,"猪肉脯","良品铺子"));
		set.add(new Item(9.9,"酸奶","aac"));
		System.out.println(set);
}		
public class CompareByPriceAndBrand implements Comparator{

   @Override
   public int compare(Object o1, Object o2) {//o1和o2是两个比较对象
	   Item item1 = (Item)o1;
	   Item item2 = (Item)o2;
	   //先比较价格
	   double temp = item1.getPrice() - item2.getPrice();
	   //判断价格是否相等,如果相等就根据商家的品牌名进行排序
	   if(temp == 0) {
		  return item1.getBrand().compareTo(item2.getBrand());
	   }
	   return (int)temp;
   }
}


输出结果

[Items [price=9.9, name=酸奶, brand=aac], Items [price=9.9, name=锅巴, brand=zbc], Items [price=18.9, name=猪肉脯, brand=良品铺子], Items [price=24.8, name=夏威夷果, brand=三只松鼠]]

2. 双列集合

Map集合是双列集合,是以键值对的形式存储数据的,既一对一的映射关系

Map集合中key值不能重复的,同时,key所对应的值至多为一个。

但是值是可以重复的,重复的两个值对应不同的key

  • 添加方法
	/**
	  * 添加方法
	  */
	public static void putMethod() {
			Map map = new HashMap();
			map.put("name","锅巴");
			map.put("price",10);
			map.put("brand","好趣味");
			
			System.out.println("map--"+map);
			map.put("price",20);
			System.out.println("map添加后--"+map);
			//key值相同的情况下,会进行值的覆盖
			map.put(null,null);
			System.out.println("map空值实例--"+map);
			
			//如何存自定义类型
			Map map2 = new HashMap();
			Item item = new Item("夏威夷果","三只松鼠",18.9);
			map2.put(item, 1);
			map2.put(2, new Item("腰果","百草味",25.9));
			System.out.println("map2"+map2);
			
			
			map.putAll(map2);
			System.out.println("移除交集后--"+map);
	}
	
	
	结果:
	map--{price=10, name=锅巴, brand=好趣味}
	map添加后--{price=20, name=锅巴, brand=好趣味}
	map空值实例--{null=null, price=20, name=锅巴, brand=好趣味}
	map2{2=Item [name=腰果, brand=百草味, price=25.9], Item [name=夏威夷果, brand=三只松鼠, price=18.9]=1}
	移除交集后--{null=null, 2=Item [name=腰果, brand=百草味, price=25.9], price=20, name=锅巴, brand=好趣味, Item [name=夏威夷果, brand=三只松鼠, price=18.9]=1}
  • 移除方法
public static void removeMethod() {
		Map map = new HashMap();
		map.put("name","锅巴");
		map.put("price",10);
		map.put("brand","好趣味");
		System.out.println("map--"+map);
		
		map.remove("brand");
		System.out.println("map删--"+map);
		map.remove("name","烧饼");//要是想删键和对应的值,就要都写对
		System.out.println("map删2--"+map);
		map.remove("price",10);
		System.out.println(map);
		
		map.clear();//清空集合
		System.out.println(map);
		System.out.println(map.size());//集合内元素数量
				
} 

结果:
map--{price=10, name=锅巴, brand=好趣味}
map删--{price=10, name=锅巴}
map删2--{price=10, name=锅巴}
{name=锅巴}
{}
0
  • 获取方法
/**
  * 获取方法
  */
	public static void getMethod(){
		Map map = new HashMap();
		map.put("name","锅巴");
		map.put("price",10);
		map.put("brand","好趣味");
		System.out.println(map.get("brand"));
	}
	
结果:
好趣味
  • 如何进行遍历

三种方法,collection,keySet(),和entrySet()

  • values 以Collection的形式进行遍历
public static void ergodicMethod() {
	Map map = new HashMap();
	map.put("name","锅巴");
	map.put("price",10);
	map.put("brand","好趣味");
	Collection coll = map.values();
	Iterator it = coll.iterator();
	while(it.hasNext()) {
		System.out.println(it.next());
	}
}
  • keySet() 将所有的key封装成一个Set集合进行遍历
  • Map集合中要求key是不能重复的,而Set集合本身就是不重复的
public static void ergodicMethod2() {
		Map map = new HashMap();
		map.put("name","锅巴");
		map.put("price",10);
		map.put("brand","好趣味");
		Set set = map.keySet();
		Iterator it = set.iterator();
		while (it.hasNext()) {
			Object key = it.next();
			Object value = map.get(key);
			System.out.println("key为"+key+" "+"value值为"+value);
		}	
}
  • entrySet() 将整个映射作为一个整体进行使用,返回值类型Set<Map.Entry> Map.Entry是Map集合中的一个内部接口
public static void ergodicMethod3() {
		Map map = new HashMap();
		map.put("name", "锅巴");
		map.put("price", 10);
		map.put("brand", "好趣味");
		Set set = map.entrySet();
		// 迭代器中存储的整个键对值关系 ---- Entry 因为是一个内部接口, 将map整体封装进去Entry,再写上setget方法来获取key和value
		Iterator it = set.iterator();
		while (it.hasNext()) {
			Map.Entry entry = (Map.Entry) it.next();
			Object key = entry.getKey();
			Object value = entry.getValue();
			System.out.println("key为" + key + " " + "value值为" + value);
		}

}
  • TreeMap的排序 (基于key来进行自然排序)
	public static void orderMethod() {
			Map map = new TreeMap();
			map.put("name", "锅巴");
			map.put("price", 10);
			map.put("brand", "好趣味");
			System.out.println(map);	
			
			
			//基于比较器的自定义类型排序
		    Map map2 = new TreeMap(new CompareByPriceAndBrand());
			map2.put(new Item("夏威夷果", "sanzhisongshu", 9.9), "自定义类型1");
			map2.put(new Item("腰果", "liangpinpuzi", 12.3), "自定义类型2");
			map2.put(new Item("碧根果", "baicaowei", 9.9), "自定义类型3");
			System.out.println(map2);
	}
	
	
	class CompareByPriceAndBrand implements Comparator{
	
		@Override
		public int compare(Object o1, Object o2) {//o1和o2是两个比较对象
			Item item1 = (Item)o1;
			Item item2 = (Item)o2;
			//先比较价格
			double temp = item1.getPrice() - item2.getPrice();
			//判断价格是否相等,如果相等就根据商家的品牌名进行排序
			if(temp == 0) {
				return item1.getBrand().compareTo(item2.getBrand());
		    }
		    return (int)temp;
	    }
	
	}
	结果
	{brand=好趣味, name=锅巴, price=10}
	{Item [name=碧根果, brand=baicaowei, price=9.9]=自定义类型3, Item [name=夏威夷果, brand=sanzhisongshu, price=9.9]=自定义类型1, Item [name=腰果, brand=liangpinpuzi, price=12.3]=自定义类型2}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值