day-2-4-2

Set接口概述:元素无序、不可重复

  • Set接口是Collection的子接口,set接口没有提供额外的方法
  • Set集合不允许包含相同的元素,如果试把两个相同的元素加入同一个Set 集合中,则添加操作失败。
  • Set判断两个对象是否相同不是使用 == 运算符,而是根据 equals() 方法
Set接口的实现类
  • HashSet

    不保证元素的添加顺序,底层采用哈希表算法,查询效率高。判断两个元素是否相等equals方法返回为true要求hashCode值必须相等。即要求存入HashSet中的元素要覆盖equals方法和hashCode方法

    LinkedHashSet

    HashSet的子类,底层采用了哈希表算法以及链表算法,既保证了元素的添加顺序,也保证了查询效率。但是整体性能要低于HashSet

  • TreeSet

    不保证元素的添加顺序,但是会对集合中的元素进行排序。底层采用红-黑树算法,树结构比较适合查询,但是添加的效率较低

各种Set集合性能分析
  • HashSet和TreeSet是Set集合中用得最多的集合。HashSet总是比TreeSet集合性能好,因为HashSet不需要额维护元素的顺序。

  • LinkedHashSet需要用额外的链表维护元素的插入顺序,因此在插入时性能比HashSet低,但在迭代访问(遍历)时性能更高。因为插入的时候即要计算hashCode又要维护链表,而遍历的时候只需要按链表来访问元素。

  • EnumSet元素是所有Set元素中性能最好的,但是它只能保存枚举类型的元素。

相关的集合计算
  • addAll将指定集合中的所有元素都添加到此集合中,如果在进行此操作的同时修改了指定的集合,那么将不能保证操作的正确性
  • removeAll从指定的集合中移除包含在另一个集合中的元素,返回值为boolean,如果包含了要移除的对象则返回true否则false
  • retainAll仅仅保留集合中同时包含在指定集合的对象,其它的全部移除
  • containsAll用来查看在该集合中是否存在在指定集合中的所有对象,返回true表示存在,否则false
Collection和Collections的区别 [面试]

Collection是java.util下的接口,它是各种集合的父接口,继承于它的接口主要有Set和List

Collections是个java.util下的类,是针对集合的帮助类,提供一系列静态方法实现对各种集合的搜索、排序、线程安全化等操作

  • Arrays工具类,是针对数组的帮助类,提供一系列静态方法实现对各种数组的搜索、排序等操作
  •  sort排序 具体实现 list.sort(null);
    
  •  binarySearch(list, 7)折半查找   可以返回在list中的下标
    
  •  fill填充数据  
    
  •  copyOf拷贝数组 
    
  •  hashCode获取一个数组的hash值
    
  •  toString将数组转换为友好显示的字符串
    
线程安全化

ArrayList和LinkedList线程不安全,针对线程安全的需求一般也不建议使用Vector

synchronizedXxx

List<Integer> list=Collections.synchronizedList(new ArrayList<>());

具体实现是在原来数据操作的基础上添加了一个全局锁

练习
  • 使用Set集合删除List集合中的重复值
public class Test3 {
	public static void main(String[] args) {
		Random r = new Random();
		List<Integer> list = new ArrayList<>();
		for (int i = 0; i < 20; i++)
			list.add(r.nextInt(10));
		System.out.println(list);
		Set<Integer> set = new LinkedHashSet<>(list);
		System.out.println(set);
	}
}
  • 有一篇英文文章,请获取其中有哪些字符(去重复)
public class Test4 {
	public static void main(String[] args) throws Exception {
		Reader r = new BufferedReader(new FileReader("Test1.java"));
		Set<Character> set = new HashSet<>();
		int kk=-1;
		while((kk=r.read())!=-1) {
			set.add((char)kk);
		}
		r.close();  //try/finally  try-resource
		System.out.println(set);
	}
}
  • 有一篇文章要求统计每个字符的出现次数,并按照出现次数排序后输出
    • 不知道可能的字符个数所以只能考虑使用集合
    • 需要记录字符和对应的出现次数,所以定义一个用于数据传输的类DTO
      字符和对应的出现次数 --Map
    • 需要进行排序,使用TreeSet
    • 直接存储元素到到TreeSet然后再修改出现次数—错误
      • 使用StringBuilder出现位置记录字符出现在集合中的位置–布隆过滤器的原理
    • 需要读取文本中的字符,所以使用BIO中的字符流
public class Test5 {
	public static void main(String[] args) throws IOException {
		Reader r = new BufferedReader(new FileReader("Test1.java"));
		List<CharNum> list = new LinkedList<>();
		int kk = -1;
		while ((kk = r.read()) != -1) {
			// 如果集合中没有对应的字符则添加到集合中;如果已经包含了该字符则修改出现次数
			CharNum cn = new CharNum((char) kk);
			int pos = list.indexOf(cn);
			if (pos > -1) {
				cn = list.get(pos);
				cn.setNum(cn.getNum() + 1);
			} else
				list.add(cn);
		}
		r.close();
		Set<CharNum> set = new TreeSet<>(list);
		
		System.out.println(set);
	}
}

class CharNum implements Comparable<CharNum> {
	private char c;
	private int num;

	public CharNum(char c) {
		super();
		this.c = c;
		this.num = 1;
	}

	public char getC() {
		return c;
	}

	public void setC(char c) {
		this.c = c;
	}

	public int getNum() {
		return num;
	}

	public void setNum(int num) {
		this.num = num;
	}

	@Override
	public String toString() {
		return "CharNum [c=" + c + ", num=" + num + "]";
	}

	@Override
	public int hashCode() {
		return Objects.hash(c);
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		CharNum other = (CharNum) obj;
		return c == other.c;
	}

	@Override
	public int compareTo(CharNum o) {
		// 首先按照出现次数排序,如果出现次数相等,则按照字符排序
		int res = num - o.num;
		if (res == 0)
			res = c - o.c;
		return res;
	}

}

Objects工具类

Objects类是Final的,即不可以被其他类继承,并且它里面的方法都是static的

  • equals方法的功能是判断两个对象 是否是同一个对象, 或者两个对象是否相等。重点是处理了比较对象为null

  • deepEquals就比较严格一点,首先它比较两个对象是否是同一个对象;如果不是,再判断它们是否是矩阵,对于矩阵的每个元素,它们是否是同一个对象;最后调用对象的equals方法

  • hashCode(Object)是计算单个对象的hashCode,这里处理了null,hashCode(Object…)是计算矩阵的hashCode

  • toString方法是一个加强版的toString,多了一个null处理

  • requireNonNull判断非null requireNonNull(Object) 如果obj为null,则异常NullPointerException

  • isNull对象是否为Null,nonNull判断对象是否非null,不抛异常

List接口的新方法

获取一个不可变的集合,其中的元素不允许修改,只能读取,具体实现类为ListN
List<Integer> list = List.of(10,12,30,5,56,47);

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值