Day24-集合(下)

集合(下)

泛型集合

概念

参数化类型,类型安全的集合,强制集合元素的类型必须一致

特点

编译时即可检查,而非运行时抛出异常

访问时,不必类型转换(拆箱)

不同泛型之间引用不能相互赋值,泛型不存在多态

Collections工具类

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * 位于java.utils包下
 * 封装了与集合相关的静态方法
 * 构造方法私有
 */
public class TestCollections {
	public static void main(String[] args) {
		//无参构造私有,不能直接new
		//Collections collections = new Collections();
		List<Integer> list = new ArrayList<Integer>();
		list.add(20);
		list.add(28);
		list.add(8);
		list.add(4);
		list.add(56);
		System.out.println("排序前:"+list);
		
		//排序
		//无返回值不可打印
		Collections.sort(list);
		System.out.println("排序后:"+list);
		System.out.println("--------------");
		
		//二分查找
		System.out.println(Collections.binarySearch(list, 8));
		System.out.println("--------------");
		
		//复制(不是真的复制 覆盖)
		ArrayList<Integer> list2 = new ArrayList<Integer>();
		//覆盖空间和最大空间有关
		for (int i = 0; i < 6; i++) {
			list2.add(12);
		}
		//快速填充
		//Collections.fill(list2, 3);
		System.out.println("复制前集合是:"+list2);
		Collections.copy(list2, list);
		System.out.println("list集合是:"+list);
		System.out.println("复制后集合是:"+list2);
		
		//反转
		System.out.println("原顺序:"+list2);
		Collections.reverse(list2);
		System.out.println("反转后:"+list2);
		
		//打乱方法
		System.out.println("原顺序:"+list2);
		Collections.shuffle(list2);
		System.out.println("随机打乱新集合:"+list2);
		
		//数组与集合之间的转换
		//数组转集合 asList 【注意】可修改,不可添加删除 会造成数组下标越界问题
		String [] names = {"张三","李四","王二麻子"};
		List<String> namesList = Arrays.asList(names);
		System.out.println(namesList);
		//namesList.add("二狗");
		//System.out.println(namesList);
		
		//集合转数组 toArray
		String[] array = namesList.toArray(new String[namesList.size()]);
		System.out.println(Arrays.toString(array));
		//打印地址,转成数组成功
		System.out.println(array);
		
		//addAll()全加进去
		ArrayList<Integer> list3 = new ArrayList<Integer>();
		System.out.println(list3);
		System.out.println("11111");
		Collections.addAll(list3, 10,20,30,40,50,60);
		System.out.println(list3);
		
		//面试题 扩容几次? 0次,有参构造,大于10,直接new数组
		ArrayList list4 = new ArrayList(20);
	}
}

Set子接口

特点

无序、无下标、元素不可重复(当插入新元素时,如果新元素与已有元素进行equals比较,结果为true时,则拒接新元素的插入)

Set接口实现类

  • HashSet【重要】

HashSet的底层使用的HashMap类,即是将所有需要存入HashSet的值,直接保存在HashMap中

HashSet如何去掉重复?

重写hashCode和equals方法,先判断hashCode是否一致,==比较地址,equals比较内容

  • LinkedHashSet

底层使用LinkedHashMap(链表结构)存储,结点形式单独存储数据,并可以指向下一个结点,通过顺序访问结点,可保留元素插入顺序

  • TreeSet

实现了SortedSet接口,要求必须可以对元素排序

所有插入元素,必须实现Comparable接口,覆盖compareTo方法

根据compareTo方法返回值作为去重的依据(0意为重复)

代码:

HashSet

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * Set集合
 */
public class TestHashSet1 {
	public static void main(String[] args) {
		//创建集合
		//接口,不能直接实例
		Set<Integer> set = new HashSet<Integer>();
		
		//添加元素
		set.add(78);
		set.add(67);
		set.add(56);
		set.add(100);
		set.add(99);
		set.add(67);
		set.add(99);
		//输出5个 不可重复
		System.out.println("元素个数:"+set.size());
		System.out.println(set);
	
//		//删除元素
//		set.remove(100);
//		System.out.println("元素个数:"+set.size());
//		System.out.println(set);
//		//清空
//		set.clear();
//		System.out.println("元素个数:"+set.size());
//		System.out.println(set);
		
		//遍历元素
		//无下标,不可以通过普通for循环遍历
		System.out.println("通过增强型for循环遍历");
		//集合类型 集合变量 : 集合名
		for (Integer integer : set) {
			System.out.println(integer);
		}
		//迭代器列表也不可以
		System.out.println("通过迭代器遍历");
		Iterator<Integer> iterator = set.iterator();
		while (iterator.hasNext()) {
			Integer integer = (Integer) iterator.next();
			System.out.println(integer);
		}
		
		//判断元素
		System.out.println(set.contains(10));
		System.out.println(set.isEmpty());

	}
}

import java.util.Objects;

public class Student {
	private int sid;
	private String name;
	private int age;
	private double score;
	
	public Student() {
		super();
	}
	
	public Student(int sid, String name, int age, double score) {
		super();
		this.sid = sid;
		this.name = name;
		this.age = age;
		this.score = score;
	}

	@Override
	public int hashCode() {
		// TODO Auto-generated method stub
		return super.hashCode();
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Student other = (Student) obj;
		return age == other.age && Objects.equals(name, other.name)
				&& Double.doubleToLongBits(score) == Double.doubleToLongBits(other.score) && sid == other.sid;
	}

	public int getSid() {
		return sid;
	}
	public void setSid(int sid) {
		this.sid = sid;
	}
	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 double getScore() {
		return score;
	}
	public void setScore(double score) {
		this.score = score;
	}
	
}

import java.util.HashSet;
/**
 * 使用Set存储复杂数据类型
 * 	特点:无序无下标,元素不能重复
 * 问题:存储自定义对象,对象重复了怎么办?
 * 类:
 * 	系统类:System 包装类 String
 * 	自定义类:HelloWorld Person Student
 * 1重写hashCode和equals方法?
 *  A.哈希表的结果
 *     数组结构+链表结构
 *  B.哈希表如何进行存储的?
 *     1.通过hashCode方法获取哈希码值x(整数的哈希码值就是其本身)
 *     2.通过表达式y=kx(计算在数组结构中找存储位置) y
 *     3.如果y值位置为空,直接插进入,如果不为空,调用equals方法进行比较
 *  C.哈希表如何进行查询的?
 *     查询结果:  一次查询  多次查询  查询不到
 *     删除:先找再删
 *     为什么哈希表存储、删除、查询都很快?(因为底层结构决定,数组结构+链表结构)
 *  D.哈希表如何保证数据不重复
 *    1.取余使用质数  如:11 31 
 *    2.哈希表底层尽量避免重复                                    如果依次比较链表中所有数据相等,直接去除。
 *  E.各个数据类型哈希码值如何获取?
 *    A.整型:整数的哈希码值就是其本身
 *    B.浮点型:浮点型哈希码值不是其本身 通过底层方法封装
 *    C.字符型:其对应的整数值
 *    D.字符串:分别获取单个字符做计算
 *    E.自定义类:分别对各个属性进行计算
 * 
 *	hashSet是如何去重的?(重写hashCode和equals方法的作用?)
 *		重写hashCode和equals方法,
 *		存入的哈希码相同时,会调用== 和equals进行比较,结果为true,拒接后者加入
 */
public class TestStudent {
	public static void main(String[] args) {
		//创建集合
		HashSet<Student> stuSet = new HashSet<Student>();
		
		//添加元素
		Student s1 = new Student(1001,"aa",19,98.5);
		Student s2 = new Student(1002,"bb",20,100);
		Student s3 = new Student(1003,"cc",18,89);
		Student s4 = new Student(1001,"aa",19,98.5);
		
		stuSet.add(s1);
		stuSet.add(s2);
		stuSet.add(s3);
		stuSet.add(s4);
		System.out.println("元素个数:"+stuSet.size());
		System.out.println(stuSet);
		
//		删除元素
//		stuSet.remove(new Student(1001, "aa", 19, 98.5));
//		System.out.println("元素个数:"+stuSet.size());
//		System.out.println(stuSet);
//		stuSet.clear();
//		System.out.println("元素个数:"+stuSet.size());
		
		//判断元素
//		整数的哈希码值就是其本身
		System.out.println(Integer.hashCode(12));
		System.out.println(new Integer(12).hashCode());
		System.out.println(Double.hashCode(3.14));
		System.out.println(new Double(3.14).hashCode());
		System.out.println(Character.hashCode('a'));
		System.out.println(new Character('a').hashCode());
		System.out.println("----------------------------");
		System.out.println(new String("a").hashCode());//97  =97*31^0
		System.out.println(new String("aa").hashCode());//3104 = 97*31+97
		System.out.println(new String("aaa").hashCode());//96321   97*31*31+97*31+97=93217+3104
		
	}
}

LinkedHashSet

import java.util.Iterator;
import java.util.LinkedHashSet;

/**
 * Set集合
 * 特点:无序、无下标、元素不可重复。
 * 方法:全部继承自Collection中的方法。
 * LinkedHashSet:
          链表实现的HashSet,按照链表进行存储,即可保留元素的插入顺序。  
 */
public class TestHashSet2 {
	public static void main(String[] args) {
		//创建集合
//		HashSet<Integer> set=new HashSet<Integer>();
		LinkedHashSet<Integer> set=new LinkedHashSet<Integer>();
		//添加元素
		set.add(78);
		set.add(67);
		set.add(56);
		set.add(100);
		set.add(99);
		set.add(67);
		set.add(99);
	
		System.out.println("元素个数:"+set.size());
		System.out.println(set);	
		//遍历元素
		System.out.println("通过for循环遍历");
//		for(int i=0;i<set.size();i++) {
//			set.get
//		}
		System.out.println("增强for循环遍历:");
		for(Integer i :set) {
			System.out.println(i);
		}
		System.out.println("通过迭代器遍历:");
		Iterator<Integer> it = set.iterator();
		while(it.hasNext()) {
			System.out.println(it.next());
		}
		//判断元素
		System.out.println(set.contains(10));
		System.out.println(set.isEmpty());
	}
}

TreeSet

public class Student implements Comparable<Student>{
	private int sid;
	private String name;
	private int age;
	private double score;
	public int getSid() {
		return sid;
	}
	public void setSid(int sid) {
		this.sid = sid;
	}
	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 double getScore() {
		return score;
	}
	public void setScore(double score) {
		this.score = score;
	}
	@Override
	public String toString() {
		return "Student [sid=" + sid + ", name=" + name + ", age=" + age + ", score=" + score + "]";
	}
	
	public Student() {
		super();
	}
	
	public Student(int sid, String name, int age, double score) {
		super();
		this.sid = sid;
		this.name = name;
		this.age = age;
		this.score = score;
	}
	public int compareTo(Student o) {
		return this.sid - o.sid;//升序
//		return o.sid - this.sid;降序
//		//先比姓名
//		int n1 = this.name.compareTo(o.name);
//		//再比年龄
//		int n2 = this.age - o.age;
//		return n1 == 0 ? n2 : n1;
	}
	
}

import java.util.Comparator;
import java.util.TreeSet;
/**
 * 和hashCode,equals没关系
 * 
 */
public class TestStudent {
	public static void main(String[] args) {
		//创建集合时,如果元素没有实现Comparable接口,可以自定义比较器Comparator
		//匿名内部类
		Comparator<Student> comparator = new Comparator<Student>() {
			@Override
			public int compare(Student o1, Student o2) {
				//就近原则
				System.out.println("进来了");
				return o2.getSid() - o1.getSid();
			}
		};
		
		
		//创建集合对象
		//自定义比较器优先级高于元素排序顺序
		TreeSet<Student> stuTree = new TreeSet<Student>(/*comparator*/);
		//添加元素
		Student s1 = new Student(1001,"aa",19,98.5);
		Student s2 = new Student(1002,"bb",20,100);
		Student s3 = new Student(1003,"cc",18,97.5);
		Student s4 = new Student(1001,"aa",19,98.5);
		
		stuTree.add(s1);
		stuTree.add(s2);
		stuTree.add(s3);
		stuTree.add(s4);
		System.out.println("元素个数"+stuTree.size());
		System.out.println(stuTree);
		
		//删除元素
//		stuTree.remove(new Student(1001, "aa", 19, 98.5));
//		System.out.println("元素个数:"+stuTree.size());
//		stuTree.clear();
//		System.out.println("元素个数:"+stuTree.size());
		//遍历元素
		//增强for
		//迭代器
		//判断元素
		System.out.println(stuTree.contains(new Student(1001, "aa", 19, 98.5)));
		System.out.println(stuTree.isEmpty());
	}
	
}

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.TreeSet;

/**
 * 实现字符串按照长度排序,如果长度相同,按照编码顺序。
 *
 */
public class TestComparator {
	public static void main(String[] args) {
		
Comparator<String> comparator=new Comparator<String>() {
			
			@Override
			public int compare(String o1, String o2) {
				//按照长度排
				int n1=o1.length()-o2.length();
				//按照字典
				int n2=o1.compareTo(o2);
				return n1==0?n2:n1;
			}
		};
		
		//创建集合
		TreeSet<String> set = new TreeSet<String>();
		//添加元素
		set.add("A");
		set.add("B");
		set.add("a");
		set.add("aa");
		set.add("0123");
		set.add("Z");
		//遍历元素
		System.out.println(set);//[0123, A, B, Z, a, aa]

		ArrayList<Integer> list=new ArrayList<Integer>();
		Collections.addAll(list, 12,45,22,78,9);
		System.out.println("原序:"+list);
		Collections.sort(list, new Comparator<Integer>() {

			@Override
			public int compare(Integer o1, Integer o2) {
				
				return o2-o1;
			}
		});
		System.out.println(list);
	}
}

import java.util.Iterator;
import java.util.TreeSet;
/**
 * Set集合:无序 唯一
 * TreeSet:自然顺序
 * TreeSet:红黑树(二叉树)
 *        中序遍历
 */
public class TestTreeSet {
	public static void main(String[] args) {
		//创建集合对象
		TreeSet<Integer> set = new TreeSet<Integer>();
		//添加元素
		set.add(78);
		set.add(67);
		set.add(56);
		set.add(100);
		set.add(99);
		set.add(67);
		set.add(99);
		System.out.println("元素的个数:"+set.size());
		System.out.println(set);//[56, 67, 78, 99, 100]
		
		//删除元素
//		set.remove(67);
//		System.out.println("元素的个数:"+set.size());
//		System.out.println(set);//[56, 78, 99, 100]
//		set.clear();
//		System.out.println("元素的个数:"+set.size());
		
		//遍历元素
		System.out.println("增强for循环遍历:");
		for (Integer integer : set) {
			System.out.println(integer);
		}
		System.out.println("迭代器遍历:");
		Iterator<Integer> it = set.iterator();
		while (it.hasNext()) {
			System.out.println(it.next());
		}
		//判断元素
		System.out.println(set.contains(67));
		System.out.println(set.isEmpty());
	}
}

Map

未完待续...

posted @ 2021-08-04 21:35  CN_Darren  阅读(48)  评论(0)    收藏  举报