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
未完待续...

浙公网安备 33010602011771号