7.7Set集合

Set集合用于存储不重复的元素,且set集合为了满足不重复都特点,需要实现equals和hashCode方法。
Set提供的方法:

  • 将元素添加进Set:boolean add(E e)
  • 将元素从Set删除:boolean remove(Object e)
  • 判断是否包含元素:boolean contains(Object e)

例:

public class Main {
    public static void main(String[] args) {
        Set<String> set = new HashSet<>();
        System.out.println(set.add("abc")); // true
        System.out.println(set.add("xyz")); // true
        System.out.println(set.add("xyz")); // false,添加失败,因为元素已存在
        System.out.println(set.contains("xyz")); // true,元素存在
        System.out.println(set.contains("XYZ")); // false,元素不存在
        System.out.println(set.remove("hello")); // false,删除失败,因为元素不存在
        System.out.println(set.size()); // 2,一共两个元素
    }
}

常用的set集合:

  • HashSet:
    特点:无序、内部实现了HashMap,可以看做是没有vlaue的HashMap
    核心代码:

    public class HashSet<E> implements Set<E> {
        // 持有一个HashMap:
        private HashMap<E, Object> map = new HashMap<>();
    
        // 放入HashMap的value:
        private static final Object PRESENT = new Object();
    
        public boolean add(E e) {
            return map.put(e, PRESENT) == null;
        }
    
        public boolean contains(Object o) {
            return map.containsKey(o);
        }
    
        public boolean remove(Object o) {
            return map.remove(o) == PRESENT;
        }
    }
    
  • SortSet(接口):实现类:TreeSet
    特点:有序、与TreeSet相似,同样需要实现Comparable接口,实现compare方法
    例:

public class Main {
    public static void main(String[] args) {
        Set<String> set = new TreeSet<>();
        set.add("apple");
        set.add("banana");
        set.add("pear");
        set.add("orange");
        for (String s : set) {
            System.out.println(s);
        }
    }
}
输出:
apple
banana
orange
pear

如果没有实现Comparable接口,那么创建TreeSet时必须传入一个Comparator对象。
练习:给出一组List,设置为set集合,且需不重复和有序。

package SetPro;

import java.util.*;

public class SetTest {

	public static void main(String[] args) {
		List<Message> received = new ArrayList<Message>();//创建ArrayList
		
		Message message1 = new Message(1, "Hello!");
		Message message2 =new Message(2, "发工资了吗?");
		Message message3 = new Message(2, "发工资了吗?");
		Message message4 = new Message(3, "去哪吃饭?"); 
		Message message5 = new Message(3, "去哪吃饭?");
		Message message6 = new Message(4, "Bye");

		received.add(message1);
		received.add(message2);
		received.add(message3);
		received.add(message4);
		received.add(message5);
		received.add(message6);
		
		List<Message> list = new ArrayList<Message>();

		
	        List<Message> displayMessages = process(received);

	        for (Message message : displayMessages) {
				System.out.println(message.text);
			}
	}

	static List<Message> process(List<Message> received) {
		// TODO: 按sequence去除重复消息
		Set<Message> set = new TreeSet<Message>(new Comparator<Message>() {
			public int compare(Message o1, Message o2) {
				return o1.text.compareTo(o2.text);
			}
		});

		Iterator<Message> setIterator = set.iterator(); //一个set集合的迭代器
		
		for (int i = 0; i < received.size(); i++) {
			boolean b = set.add(received.get(i));//在set集合中添加list元素,返回值为Boolean类型,添加成功返回true,否则false
			if(b) {//判断是否成功
				received.remove(i);//成功则在list集合中移除该元素,
				if(setIterator.hasNext()) {//判断set集合中是否有值,有值则取出存入list集合
					received.add(setIterator.next());//在list集合中添加set中的元素
				}else {
					continue;
				}
			}else {
				continue;
			}
		}
		return received;
	}
}

class Message {
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + sequence;
		result = prime * result + ((text == null) ? 0 : text.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;
		Message other = (Message) obj;
		if (sequence != other.sequence)
			return false;
		if (text == null) {
			if (other.text != null)
				return false;
		} else if (!text.equals(other.text))
			return false;
		return true;
	}
	public final int sequence;
	public final String text;

	public Message(int sequence, String text) {
		this.sequence = sequence;
		this.text = text;
	}

}

代码练习中出错,一直报java.lang.UnsupportedOperationException,并且是在remove中报错。
原因:之前list集合创建方法:

 List<Message> received = List.of(
            new Message(1, "Hello!"),
            new Message(2, "发工资了吗?"),
            new Message(2, "发工资了吗?"),
            new Message(3, "去哪吃饭?"),
            new Message(3, "去哪吃饭?"),
            new Message(4, "Bye")
        );

该方法返回的类型是ArrayList,该类型并不是java.util.ArrayList 而是 java.util.Arrays.ArrayList 是Arrays的内部类,该实现类AbstractList实现类,并没有实现removeAll方法,当调用removeAll时因为需要调用remove方法,但是java.util.Arrays.ArrayList中没有remove方法,会调用AbstractList的remove方法。
这就是使用简便方法创建list的弊端,想要使用需要实现其remove类。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值