1.Set接口
特点:元素的存储顺序,不由存放顺序而定,是无序的,并且存储的元素是不可重复的,容器有自己的一套存放顺序的规则
新增功能: static <E> Set<E> of(E... elements) 返回包含任意数量元素的不可修改集。
其他方法从Collection继承
(1)遍历:(1)增强for
(2)迭代器
//实例代码-Set接口实现类的元素遍历
public class Class001_Set {
public static void main(String[] args) {
Set<String> set = new HashSet<>();
//去重 无序
set.add("bcd");
set.add("abc");
set.add("abc");
set.add("bc");
set.add("ab");
System.out.println(set);
//遍历方式
//foreach
for(String str:set){
System.out.println(str);
}
//iterator
Iterator<String> it = set.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//新增
Set<Integer> set2 = Set.of(3,1,2,5,4);
System.out.println(set2);
//不可变
//set2.remove(3);
System.out.println(set2);
}
}
(2)HashSet(set接口的实现类)
因为是set接口的实现类,存储的元素也是无序的不可重复的,是由HashMap维护的。
底层结构: 哈希表(数组+链表+红黑树)
特点: 查询,增删效率较高 无序,去重
应用场景 : 存储数据由单个值决定的情况下,想要去重的情况下,适合使用HashSet
新增内容 : 无新增方法
注:哈希表存储自定义引用数据类型数据的去重: 需要在数据的类型中重写hashcode与equals方法,实现根据内容(成员变量的值)进行比较和计算
哈希表中hashcode与equals之间的关系(前提是重写hashcode与equals都是根据成员变量计算)
equals相等hashcode一定相等
hashcode相等,equals不一定相等
//实例代码-set接口的实现类HasSet
public class Class002_HashSet {
public static void main(String[] args) {
HashSet<Person> set = new HashSet<>();
set.add(new Person("小红",18));
set.add(new Person("小明",19));
set.add(new Person("小红",18));
set.add(new Person("小小彬",17));
System.out.println(set);
System.out.println(new Person("小红",18).hashCode());
System.out.println(new Person("小红",18).hashCode());
}
}
//定义一个类
class Person{
private String name;
private int age;
//定义构造方法
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
//定义设置器与访问器
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;
}
//重写toString方法
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
//重写equals方法
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return age == person.age &&
Objects.equals(name, person.name);
}
//重写hashCode方法
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
(3)TreeSet(set接口的实现类)
存储的元素是无序的,不可重复的,由TreeMap维护
底层结构:红黑树(平衡二叉树)
新增方法 : 数据的大小比较相关的方法,因为红黑树结构中数据已经比较过大小,默认升序
//实例代码-Set接口的实现类TreeSet
public class Class003_TreeSet {
public static void main(String[] args) {
TreeSet<Double> tree = new TreeSet<>();
tree.add(3.3);
tree.add(1.1);
tree.add(2.2);
tree.add(4.4);
tree.add(5.5);
tree.add(5.5);
System.out.println(tree);
//测试新增 方法
System.out.println(tree.first());
System.out.println(tree.last());
System.out.println(tree.ceiling(2.1));
System.out.println(tree.floor(3.3));
TreeSet<String> tree2 = new TreeSet<>();
tree2.add("abc");
tree2.add("bc");
tree2.add("ab");
tree2.add("a");
tree2.add("b");
tree2.add("ab");
System.out.println(tree2);
}
}
在存储自定义引用数据类型数据的时候,对象数据不确定比较规则,在TreeSet无法实现比较,无法排序,这时应该指定引用类数据的比较规则。
内部比较规则(也叫内部比较器|自然排序):
实现一个java.lang.Comparable接口,重写compareTo方法,在compareTo方法内部指定比较规则,compareTo 返回值是int类型。
T1.compareTo(T2)-> 0;相等(去重)
整数:T1>T2
负数:T1<T2
定义在类的内部,是一种默认的比较规则
缺点: 比较局限,不够灵活,硬编码,不便于后期维护
//实例代码-TreeSet实现类内部排序(引用类型,指定比较规则)
public class Class03_Treeset {
public static void main(String[] args) {
TreeSet<Person1> tree1 = new TreeSet();
tree1.add(new Person1("a",20));
tree1.add(new Person1("c",22));
tree1.add(new Person1("b",21));
System.out.println(tree1);
}
}
//定一个类 使用Comparable接口
class Person1 implements Comparable<Person1>{
private String name;
private int age;
//构造器
public Person1(String name, int age) {
this.name = name;
this.age = age;
}
//设置器与访问器
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;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
//重写compareTo方法,规定比较名字排序
@Override
public int compareTo(Person1 o) {
return o.name.compareTo(this.name);
}
}
外部比较规则(也叫外部比较器|定制排序):
定义在javabean类的外部,单独指定某种数据的某种比较规则
使用的时候,可以指定使用哪一个外部比较规则,没有指定外部比较规则,默认需要内部
实现一个接口Comparator接口,重写int compare(To1, To2) 方法,方法内部指定两个参数的比较规则
//实现类TreeSet-外部比较
public class Class004_TreeSet {
public static void main(String[] args) {
//TreeSet<Student> tree = new TreeSet<>(); 默认比较器
//TreeSet<Student> tree = new TreeSet<>(new Demo2()); //指定使用某种 外部比较器
//使用lambda代替没有本身自己作用的实现类Demo,Demo2,要求接口为函数式接口
TreeSet<Student> tree = new TreeSet<>((s1,s2)->s1.getAge()-s2.getAge());
tree.add(new Student(103,"zhangsan",19));
tree.add(new Student(102,"lisi",17));
tree.add(new Student(101,"zhangsan",18));
tree.add(new Student(101,"wangwu",16));
System.out.println(tree);
}
}
//外部比较规则: 按照年龄做降序排序
class Demo implements Comparator<Student>{
/*
compare(s1,s2)
0 s1=s2
负数 s1<s2
整数 s1>s2
*/
@Override
public int compare(Student o1, Student o2) {
return o1.getAge()-o2.getAge();
}
}
//学生姓名升序(又定义了一个规则)
class Demo2 implements Comparator<Student>{
@Override
public int compare(Student o1, Student o2) {
return o1.getName().compareTo(o2.getName());
}
}
2.Map接口
Map也是容器的一种,但是没有继承Collection接口,以键值对的形式存放数据,==一个key对应一 个value==。key和value都是引用数据类型,我们可以通过key找到对应的value Map类中存储的键-值对通过键来标识,所以键值不能重复 ,键值对为一个映射关系。
key,value可以为任意引用数据类型的数据
key--> 唯一的,无序的 --> Set集合
value --> 无序的,可重复的 -->Collection
//实例代码-Map接口的实现类对象特点
public class Class001_Map {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<>();
//常用方法
//V put(K key, V value) 返回被覆盖的value,如果没有覆盖返回null
System.out.println(map.put(103,"胡歌"));
System.out.println(map.put(104,"胡歌"));
System.out.println(map.put(102,"彭于晏"));
System.out.println(map);
System.out.println(map.put(104,"胡一菲"));
System.out.println(map);
/*
boolean containsKey(Object key) 如果此映射包含指定键的映射,则返回 true 。
boolean containsValue(Object value) 如果此映射将一个或多个键映射到指定值,则返回 true 。
*/
System.out.println(map.containsKey(104));
System.out.println(map.containsValue("胡歌"));
//V get(Object key) 返回指定键映射到的值,如果此映射不包含键的映射,则返回 null 。
System.out.println(map.get(102));
//static <K,V> Map<K,V> of(K k1, V v1) 返回包含单个映射的不可修改的映射。
Map<String,Integer> map2 = Map.of("zhangsan",18,"lisi",19);
System.out.println(map2);
//V remove(Object key) 如果存在,则从该映射中移除键的映射(可选操作)。
System.out.println(map.remove(101));
System.out.println(map);
//default V replace(K key, V value) 仅当指定键当前映射到某个值时,才替换该条目的条目。
map.replace(103,"胡哥哥");
System.out.println(map);
}
}
(1)遍历
Map集合的遍历方式:
1.keySet() 获取集合中所有的key,然后遍历key,根据key获取value
2.values() 获取集合中所有的value
3.entrySet() 返回多个Map.Entry类型的键值对对象,一个set集合
//Map的元素遍历的三种方式
public class Class002_Map {
public static void main(String[] args) {
Map<Integer,String> map = new HashMap<>();
map.put(103,"胡歌");
map.put(104,"胡歌");
map.put(102,"彭于晏");
map.put(105,"胡一菲");
//1.keySet
Set<Integer> keys = map.keySet();
for(Integer i : keys){
System.out.println(i+"-->"+map.get(i));
}
//2.values()
Collection<String> values = map.values();
Iterator<String> it = values.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
//3.entrySet()
Set<Map.Entry<Integer,String>> set = map.entrySet();
for(Map.Entry entry:set){
System.out.println(entry.getKey()+"-->"+entry.getValue());
}
}
}
(2)HashMap(Map接口的实现类)
底层: 哈希表(数组+链表+红黑树)
特点: 查询,增删效率较高
新增方法: 无新增方法
遍历方式: 与map相同
并允许null值和null键
DEFAULT_LOAD_FACTOR : 默认的加载因子 0.75
DEFAULT_INITIAL_CAPACITY : 默认初始容量 1<<4 = 16
threshold 扩容临界值 | 阀值 CAPACITY*LOAD_FACTOR
扩容: newCap = oldCap << 1 每次扩容原数组容量的2倍
/* 练习: 定义一个HashMap结构,用来存储指定类型的数据,要求存储key为Teacher,value为Teacher所教授的学科*/
public class Class03_HashMap {
public static void main(String[] args) {
//构建一个HashMap
HashMap<Teacher,String> map = new HashMap<>();
map.put(new Teacher("语文老师","语文"),"语文");
map.put(new Teacher("数学老师","数学"),"数学");
map.put(new Teacher("英语老师","英语"),"英语");
map.put(new Teacher("体育老师","体育"),"体育");
System.out.println(map);
}
}
class Teacher implements Comparable<Teacher>{
private String name;
private String project;
//构造器
public Teacher(String name, String project) {
this.name = name;
this.project = project;
}
//设置器与访问器
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getProject() {
return project;
}
public void setProject(String project) {
this.project = project;
}
@Override
public String toString() {
return "teacher{" +
"name='" + name + '\'' +
", project='" + project + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Teacher teacher = (Teacher) o;
return Objects.equals(name, teacher.name) &&
Objects.equals(project, teacher.project);
}
@Override
public int hashCode() {
return Objects.hash(name, project);
}
@Override重写方法,按教师名字排序
public int compareTo(Teacher o) {
return this.getName().compareTo(o.getName());
}
}
(3)TreeMap(Map接口的实现类)
根据key实现去重
底层结构: 红黑树
特点: 根据key对数据做升序排序
新增功能: 比较相关的一些方法
默认根据key做去重,根据key做排序
要求: key指定比较规则|方式|比较器|排序 内部比较器 外部比较器
//实例代码-TreeMap实现存储引用数据类型(键为引用数据类型,值为字符串)
public class Class004_TreeMap {
public static void main(String[] args) {
//根据key默认比较规则,对数据进行升序排序
//TreeMap<Teacher,String> tree = new TreeMap<>();
//根据实参传递的外部比较规则,对key数据进行升序排序
TreeMap<Teacher,String> tree = new TreeMap<>((t1,t2)->t1.getSubject().compareTo(t2.getSubject()));
tree.put(new Teacher("laopei",false,"java"),"java");
tree.put(new Teacher("李毅大帝",false,"db"),"db");
tree.put(new Teacher("曹老师",true,"web"),"web");
tree.put(new Teacher("曹老师",false,"web"),"前端");
System.out.println(tree);
//firstkey获取第一个元素的键
System.out.println(tree.firstKey());
//firstEntry获取第一个元素的键值对
System.out.println(tree.firstEntry()+"-->"+tree.firstEntry().getKey());
}
}
//定义Teacher继承Comoarable接口(内部比较器)
class Teacher implements Comparable<Teacher>{
private String name;
private boolean gender; //true女 false男
private String subject;
public Teacher() {
}
public Teacher(String name, boolean gender, String subject) {
this.name = name;
this.gender = gender;
this.subject = subject;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isGender() {
return gender;
}
public void setGender(boolean gender) {
this.gender = gender;
}
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", gender=" + gender +
", subject='" + subject + '\'' +
'}';
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Teacher teacher = (Teacher) o;
return gender == teacher.gender &&
Objects.equals(name, teacher.name) &&
Objects.equals(subject, teacher.subject);
}
@Override
public int hashCode() {
return Objects.hash(name, gender, subject);
}
@Override 重写compare方法,按教室名字进行排序
public int compareTo(Teacher o) {
return this.getName().compareTo(o.getName());
}
}
3.Properties
Properties为Hashtable的子类,存储的键值对都是字符串,不能为null,长与 配置文件(与外界交 互 的信息) 即内存与存储介质(文件、数据库、网络、服务器内存等)交互。
原来的集合(Set, List, Map) 都是内存中自己给数据,Peroperties 特殊在于,它自己去读取磁盘中文 件的内容,添加到集合中,直接使用有数据的集合即可(自己提供集合对象)。一般使用在配置文件中
//实例代码-Properties的使用
public class Class005_Properties {
public static void main(String[] args) throws IOException {
Properties pro = new Properties();
//设置键值对为字符串数据
/* pro.setProperty("name","张三");
pro.setProperty("pwd","123");*/
//获取键值对为字符串的数据
System.out.println(pro.getProperty("name"));
System.out.println(pro);
//void load(InputStream inStream) 从输入字节流中读取属性列表(键和元素对)。
//获取配置文件的路径,从中加载数据
pro.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties"));
//从配置文件中读取数据
System.out.println(pro.getProperty("name"));
System.out.println(pro.getProperty("pwd"));
}
}
配置文件 : properties格式,符合Properties特点: 键值对 都是字符串
4.Collections工具类
类 java.util.Collections 提供了对Set、List、Map操作的工具方法。
//实例代码-Collections工具类的使用
public class Class001_Collections {
public static void main(String[] args) {
/*
void sort(List) //对List容器内的元素排序,排序的规则是按照升序进行排序。
void shuffle(List) //对List容器内的元素进行随机排列
void reverse(List) //对List容器内的元素进行逆续排列
void fill(List, Object) //用一个特定的对象重写整个List容器
int binarySearch(List, Object)//对于顺序的List容器,采用折半查找的方法查找特定对象
*/
List<Integer> list = new ArrayList<>();
list.add(3);
list.add(1);
list.add(2);
list.add(5);
list.add(4);
System.out.println(list);
//sort 升序排序徐
Collections.sort(list);
System.out.println(list);
//sort(List<T> list, Comparator<? super T> c)
//shuffle 随机排序
//Collections.shuffle(list);
System.out.println(list);
//void reverse(List)翻转
//Collections.reverse(list);
System.out.println(list);
//binarySearch 如果找到返回索引,找不到返回-插入点-1
System.out.println(Collections.binarySearch(list,12));
}
}