目录
学习目标:
1.集合的概念 | 2.Collection体系集合 |
3.List接口与实现类 | 4.Set接口与实现类 |
5.Map接口与实现类 | 6.泛型集合与工具类 |
*.什么是集合
- 概念
- 对象的容器,实现了对对象常用的操作,类似数组的功能
- 和数组的区别
- 数组长度固定,集合长度不固定
- 数组可以存储基本类型和引用类型,集合只能存储引用类型
位置:java.util.*;
1.1Collection体系集合
1.2 Collection父接口
特点:代表一组任意类型的对象,无序、无下标、不能重复。
创建对象:Collection collection=new ArrayList();
方法:
- 1 boolean add (Object obj)//添加一个对象。
- boolean addAll(Collection c)//将一个集合中的所有对象添加到此集合中。
- void clear()//清空此集合中的所有对象。
- boolean contains(Object o)//检查此集合中是否包含o对象.
- boolean equals (Object o)//比较此集合是否与指定对象相等。
- boolean isEmpty()//判断此集合是否为空
- boolean remove(Object o)//在此集合中移除o对象. int size()//返回此集合中的元素个数。
- 0bject[] toArray()//将此集合转换成数组。
常用方法:
- 添加元素:collection.add();
- 删除元素:collection.remove();
- 遍历元素:
- 增强fo循环
- for (Object object : collection) {
}
- for (Object object : collection) {
- 迭代器
- 增强fo循环
// hasNext();看有没有下一个元素
// next();获取下一个元素
// remove();删除当前元素
System.out.println("--------------方法2:使用迭代器---------------");
Iterator it=collection.iterator();
while (it.hasNext()) {
String s = (String) it.next();
System.out.println(s);
//迭代过程当中不可以使用collection的删除方法,否则会出现错误
//it.remove();
}
4.判断元素
collection.contains();判断是否有某个元素 有true,否false
collection.isEmpty();判断是否为空 为空true,不为空false
完整代码:
package com.study.Collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/*
* Collection接口的使用
* (1)添加元素
* (2)删除元素
* (3)遍历元素
* (4)判断
* */
public class demo1 {
public static void main(String[] args) {
//创建集合-
Collection collection=new ArrayList();
// * (1)添加元素
collection.add("苹果");
collection.add("西瓜");
collection.add("香蕉");
System.out.println("元素个数"+collection.size());
System.out.println(collection.toString());
// * (2)删除元素
//collection.remove("西瓜");
//collection.clear();//清空元素
System.out.println(collection.toString());
// * (3)遍历元素(重点)
//方法1:使用增强for
for (Object object : collection) {
System.out.println(object);
}
//方法2:使用迭代器(专门用来遍历集合的一个方式)
//Iterator是一个接口
// hasNext();看有没有下一个元素
// next();获取下一个元素
// remove();删除当前元素
System.out.println("--------------方法2:使用迭代器---------------");
Iterator it=collection.iterator();
while (it.hasNext()) {
String s = (String) it.next();
System.out.println(s);
//迭代过程当中不可以使用collection的删除方法,否则会出现错误
//it.remove();
}
System.out.println("元素个数"+collection.size());
// * (4)判断
//collection.contains("");判断是否有某个元素 有true,否false
System.out.println(collection.contains("西瓜"));
//collection.isEmpty();判断是否为空 为空true,不为空false
System.out.println(collection.isEmpty());
}
}
练习代码:
package com.study.Collection;
/*
* 学生类
* */
public class Student {
private String name;
private int age;
public Student() {
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the age
*/
public int getAge() {
return age;
}
/**
* @param age the age to set
*/
public void setAge(int age) {
this.age = age;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
//Collection类
package com.study.Collection;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/*
* Collection的使用:保存学生信息
*
* */
public class demo2 {
public static void main(String[] args) {
//新建Collection对象
Collection collection=new ArrayList();
Student s1=new Student("张三", 20);
Student s2=new Student("李四",21);
Student s3=new Student("王五",22);
//添加数据
collection.add(s1);
collection.add(s2);
collection.add(s3);
collection.add(s3);//因为是ArrayList(),所以可以重复添加
System.out.println("元素个数:"+collection.size());
System.out.println(collection.toString());
//删除数据
System.out.println("-------删除数据--------");
collection.remove(s3);//删除多余的s3
System.out.println(collection.toString());
//遍历元素
System.out.println("-------增强for遍历元素--------");
for (Object object : collection) {
Student student=(Student)object;
System.out.println(student.toString());
}
System.out.println("---------迭代器----------");
Iterator iterator=collection.iterator();
while (iterator.hasNext()) {
Student s=(Student)iterator.next();
System.out.println(s.toString());
}
//判断元素
System.out.println(collection.contains(s3));
System.out.println(collection.isEmpty());
}
}
1.2List子接口
特点:有序、有下标、元素可重复
创建集合对象 :List list=new ArrayList<>();
方法:
- void add(int index,0bject o)//在index位置插入对象。
- boolean addAll(int index,Collection c)//将一个集合中的元素添加到此集合中的index位置。
- 0bject get(int index)//返回集合中指定位置的元素。
- List subList(int fromIndex,int toIndex)//返回fromIndex和toIndex之间的集合元素。
常用方法:
添加元素:list.add();
删除元素:list.remove();//是根据数组下标删除,要注意数组下标越界问题
遍历:
方法1:for循环
for (int i = 0; i < list.size(); i++) {
String s=(String)list.get(i);
System.out.println(s);
}
方法2:增强for循环
for (Object object : list) {
System.out.println(object);
}
方法3:迭代器
Iterator it=list.iterator();
while (it.hasNext()) {
String s = (String) it.next();
System.out.println(s);
}
方法4:列表迭代器
ListIterator lit=list.listIterator();
System.out.println("----------向后遍历---------");
while (lit.hasNext()) {
System.out.println(lit.nextIndex()+":"+lit.next());
}
System.out.println("----------向前遍历---------");
while (lit.hasPrevious()) {
System.out.println(lit.previousIndex()+":"+lit.previous());
}
判断:list.contains();
list.isEmpty();
获取:list.indexOf();
补充方法subLisy,返回子集合,含头不含尾:
List sunList=list.subList(1, 3);
完整代码:
package com.study.List;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/*
* List子接口的使用
*
* */
public class demo1 {
public static void main(String[] args) {
//创建集合对象
List list =new ArrayList<>();
//添加元素
list.add("苹果");
list.add("小米");
list.add(0, "华为");
System.out.println("元素个数"+list.size());
System.out.println(list.toString());
// //删除元素
// //list.remove("苹果");//单独删除
// list.remove(2);
// System.out.println("删除之后元素:"+list.size());
// System.out.println(list.toString());
//遍历
//方法1:for循环
System.out.println("-------方法1:for循环--------");
for (int i = 0; i < list.size(); i++) {
String s=(String)list.get(i);
System.out.println(s);
}
//方法2:增强for循环
System.out.println("----------方法2:增强for循环---------");
for (Object object : list) {
System.out.println(object);
}
//方法3:迭代器
System.out.println("----------方法3:迭代器---------");
Iterator it=list.iterator();
while (it.hasNext()) {
String s = (String) it.next();
System.out.println(s);
}
//方法4:列表迭代器
//listIterator与Iterator的区别 ,可以向前向后遍历,可以添加,删除,修改元素
System.out.println("----------方法4:列表迭代器---------");
ListIterator lit=list.listIterator();
System.out.println("----------向后遍历---------");
while (lit.hasNext()) {
System.out.println(lit.nextIndex()+":"+lit.next());
}
System.out.println("----------向前遍历---------");
while (lit.hasPrevious()) {
System.out.println(lit.previousIndex()+":"+lit.previous());
}
//判断
System.out.println("----------判断---------");
System.out.println(list.contains("华为"));
System.out.println(list.isEmpty());
//获取
System.out.println("----------获取---------");
System.out.println(list.indexOf("华为"));
}
}
练习代码:
package com.study.List;
import java.util.ArrayList;
import java.util.List;
public class demo2 {
public static void main(String[] args) {
List list=new ArrayList();
//添加数字类型的数值
list.add(20);
list.add(30);
list.add(40);
list.add(50);
list.add(60);
System.out.println(list.size());
System.out.println(list.toString());
//删除操作
//list.remove(20);//发生数组下标越界,无法删除
list.remove(new Integer(20));//可以把要删除的元素装箱,或则转化成Object类型
//list.remove((Object)20);
System.out.println(list.size());
//补充方法subLisy,返回子集合,含头不含尾
List sunList=list.subList(1, 3);
System.out.println(sunList.toString());
}
}
1.3List实现类
- ArrayList 【重点】
- 数组结构实现,必须要连续空间,查询快、增删慢
- jdk1.2版本,运行效率块、线程不安全
- Vector
- 数组结构实现,查询快、增删慢
- jdk1.0版本,运行
- LinkedList
- 双向链表结构实现,无需连续空间,增删快,查询慢
1.3.1ArrayList
创建集合: ArrayList arrayList = new ArrayList<>();
- 添加元素:arrayList.add();
- 删除元素:arrayList.remove();
或者:arrayList.remove(new Student("张三", 20)); 要泽洋实现要重写equals方法
重写equals后可以用数据删除
arrayList.remove(new Student("张三", 20));
@Override
public boolean equals(Object obj) {
//1.判断是否同一个对象
if (this==obj) {
return true;
}
//2.判断是否为空
if (obj==null) {
return false;
}
//3.判断是否是Student类型
if (obj instanceof Student) {
Student s=(Student)obj;
//4比较属性
if (this.name.equals(s.getName())&&this.age==s.getAge()) {
return true;
}
}
//5.不满足返回false
return false;
}
- 遍历元素(重点)
System.out.println("-----3遍历元素(重点)------");
for (int i = 0; i <arrayList.size(); i++) {
Student s=(Student)arrayList.get(i);
System.out.println(s.toString());
}
System.out.println("-----3.2迭代器------");
Iterator it=arrayList.iterator();
while (it.hasNext()) {
Student s = (Student) it.next();
System.out.println(s.toString());
}
System.out.println("-----3.2列表迭代器,从前往后------");
ListIterator lIt=arrayList.listIterator();
while (lIt.hasNext()) {
Student s=(Student) lIt.next();
System.out.println(s.toString());
}
System.out.println("-----3.2列表迭代器,从后往前------");
while (lIt.hasPrevious()) {
Student s=(Student) lIt.previous();
System.out.println(s.toString());
}
- 判断:arrayList.contains(new Student("张三", 20))
arrayList.isEmpty() - 查找:arrayList.indexOf();
完整代码:
package com.study.Collection.List.ArrayList;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
//ArrayList:
//数组结构实现,必须要连续空间,查询快、增删慢
public class demo1 {
public static void main(String[] args) {
ArrayList arrayList=new ArrayList<>();
//1添加元素
Student s1=new Student("张三", 20);
Student s2=new Student("李四", 21);
Student s3=new Student("王五", 22);
arrayList.add(s1);
arrayList.add(s2);
arrayList.add(s3);
// arrayList.add(s3);
/*
* arrayList可以重复添加某个元素,并且有序
* */
System.out.println("元素个数:"+arrayList.size());
System.out.println(arrayList.toString());
//2删除元素
System.out.println("-----2删除元素------");
//arrayList.remove(s1);
//重写equals后可以用数据删除
//arrayList.remove(new Student("张三", 20));
//arrayList.clear();
System.out.println("元素个数:"+arrayList.size());
//3遍历元素(重点)
System.out.println("-----3遍历元素(重点)------");
for (int i = 0; i <arrayList.size(); i++) {
Student s=(Student)arrayList.get(i);
System.out.println(s.toString());
}
System.out.println("-----3.2迭代器------");
Iterator it=arrayList.iterator();
while (it.hasNext()) {
Student s = (Student) it.next();
System.out.println(s.toString());
}
System.out.println("-----3.2列表迭代器,从前往后------");
ListIterator lIt=arrayList.listIterator();
while (lIt.hasNext()) {
Student s=(Student) lIt.next();
System.out.println(s.toString());
}
System.out.println("-----3.2列表迭代器,从后往前------");
while (lIt.hasPrevious()) {
Student s=(Student) lIt.previous();
System.out.println(s.toString());
}
//4判断
System.out.println("-----4判断------");
System.out.println(arrayList.contains(new Student("张三", 20)));
System.out.println(arrayList.isEmpty());
//5查找
System.out.println("-----5查找------");
System.out.println(arrayList.indexOf(s2));
System.out.println(arrayList.indexOf(new Student("张三", 20)));
}
}
1.3.2Vector
创建集合:Vector vector=new Vector();
- 增加,删除,判断,获取方法同上
- 遍历:使用枚举器(独特的)
//独有遍历方法,枚举器
Enumeration en=vector.elements();
while (en.hasMoreElements()) {
String s = (String) en.nextElement();
System.out.println(s.toString());
}
1.3.2LinkedList
创建集合:LinkedList linkedList=new LinkedList<>();
- 增加,删除,遍历,判断,获取方法同List
package com.study.Collection.List.LinkedList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
public class demo {
public static void main(String[] args) {
LinkedList linkedList=new LinkedList<>();
Student s1=new Student("张三", 20);
Student s2=new Student("李四", 21);
Student s3=new Student("王五", 22);
linkedList.add(s1);
linkedList.add(s2);
linkedList.add(s3);
for (int i = 0; i < linkedList.size(); i++) {
Student s=(Student)linkedList.get(i);
System.out.println(s.toString());
}
for (Object object : linkedList) {
Student s=(Student)object;
System.out.println(s.toString());
}
Iterator iterator=linkedList.iterator();
while (iterator.hasNext()) {
Student object = (Student) iterator.next();
System.out.println(object.toString());
}
ListIterator listIterator=linkedList.listIterator();
while (listIterator.hasNext()) {
Student object = (Student) listIterator.next();
System.out.println(object.toString());
}
}
}
2.泛型
- 本质是参数化类型,把类型作为参数传递
- 常见形式有泛型类、泛型接口、泛型方法
- 语法 T成为类型占位符,表示一种引用类型,可以写多个逗号隔开
- 好处 1. 提高代码重用性 2. 防止类型转换异常,提高代码安全性
2.1泛型类
package com.study.genericity;
public class MyGeneric<T> {
//使用泛型T
//1创建变量
T t;
//泛型作为方法的参数
public void show(T t) {
System.out.println(t);
}
//3泛型作为方法的返回值
public T geT() {
return t;
}
}
测试:
package com.study.genericity;
public class TestMyGeneric {
public static void main(String[] args) {
//使用泛型创建对象
//
MyGeneric<String> myGeneric=new MyGeneric<String>();
//注意点:在JDK1.7以前MyGeneric<>();的尖括号里面要写类型
//注意:泛型只能使用引用类型
myGeneric.t="hello";
myGeneric.show("加油,努力学习");
myGeneric.geT();
MyGeneric<Integer> myGeneric2=new MyGeneric<Integer>();
myGeneric2.t=100;
myGeneric2.show(200);
Integer integer=myGeneric2.geT();
//不同的泛型对象之间不能相互复制
//MyGeneric<String> myGeneric3=myGeneric2;
}
}
2.2泛型接口
- 语法:接口名<T>
- 注意:不能使用泛型创建静态常量
- 使用泛型接口的时候有两种情况,可以确定T的类型和不确定T的类型
package com.study.genericity;
/*
* 泛型不能直接使用要有一个实现类
* 实现这个接口的时候要把泛型告诉他
* */
public class MyInterfaceImpl implements MyInterface<String> {
@Override
public String service(String t) {
// TODO Auto-generated method stub
System.out.println(t);
return t ;
}
}
不确定
package com.study.genericity;
//当我们确定这个T的类型时,可以把类变成泛型类
public class MyInterfaceImpl2<T> implements MyInterface<T> {
@Override
public T service(T t) {
// TODO Auto-generated method stub
System.out.println(t);
return t;
}
}
测试:
MyInterfaceImpl myInterfaceImpl=new MyInterfaceImpl();
myInterfaceImpl.service("张三");
MyInterfaceImpl2<Integer> myInterfaceImpl2=new MyInterfaceImpl2<>();
myInterfaceImpl2.service(1000);
2.3泛型方法
- 语法:<T> 返回值类型
package com.study.genericity;
/*
* 泛型方法
* 语法:<T> 返回值类型
* */
public class MyGenericMethod {
public <T> T show(T t) {
System.out.println("泛型方法:"+t);
return t;
//泛型方法的T只能在自己的方法里面使用,
//不能在其他方法内使用
//哪怕在同一个类里面
}
}
测试:
//泛型方法
MyGenericMethod myGenericMethod=new MyGenericMethod();
myGenericMethod.show("张三");
myGenericMethod.show(1000);
myGenericMethod.show(3.14);
//这里的T会根据你传入的参数来决定类型
2.4泛型集合
概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致
特点:
- 编译时即可检查,而非运行时抛出异常
- 访问时,不必类型转换(拆箱)
- 不同泛型之间应用不能相互赋值,泛型不存在多态
3.1Set集合
特点:无序、无下标、元素不可重复
方法:全部继承自Collection中的方法
增、删、遍历、判断与collection一致
使用:
新建集合: Set<String> set=new HashSet<>();
添加元素: set.add();
删除元素: set.remove( );
遍历操作
1. 增强for: for (String string : set)
2. 迭代器 : Iterator<String> iterator = set.iterator( );
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
判断:set.contains( );
set
.isEmpty();
完整代码:
package com.study.Set;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class HashSetdemo {
public static void main(String[] args) {
//创建集合
Set<String> set=new HashSet<>();
//增加,删除,遍历同Collection
set.add("华为");
set.add("苹果");
set.add("小米");
//遍历【重点】
System.out.println("-------1增强for-------");
//1增强for
for (String string : set) {
System.out.println(string);
}
//2迭代器
System.out.println("-------2迭代器-------");
Iterator<String> iterator=set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
3.2HashSet[重点]
存储结构:哈希表(数组+链表+红黑树)
存储过程(重复依据)
- 根据hashCode计算保存的位置,如果位置为空,直接保存,若不为空,进行第二步
- 再执行equals方法,如果equals为true,则认为是重复,否则形成链表
特点:
- 基于HashCode计算元素存放位置
- 利用31这个质数,减少散列冲突
- 31提高执行效率
31 * i = (i << 5) - i
转为移位操作
- 31提高执行效率
- 当存入元素的哈希码相同时,会调用equals进行确认,如果结果为true,则拒绝后者存入
- 利用31这个质数,减少散列冲突
新建集合: HashSet<String> hashSet = new HashSet<>();
添加元素: hashSet.add( );
删除元素 :hashSet.remove( );
遍历操作
1. 增强for: for( String string : hashSet)
2. 迭代器 :Iterator<String> it = hashSet.iterator( );
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
判断: hashSet.contains( );
hashSet.isEmpty();
完整代码:
package com.study.Set;
import java.util.HashSet;
import java.util.Iterator;
public class HashSetdemo {
public static void main(String[] args) {
HashSet<String> hashSet=new HashSet<>();
hashSet.add("张三");
hashSet.add("李四");
hashSet.add("王五");
System.out.println(hashSet.size());
System.out.println(hashSet.toString());
// hashSet.remove("王五");
// System.out.println(hashSet.size());
System.out.println("-------1增强for-------");
for (String string : hashSet) {
System.out.println(string);
}
System.out.println("-------2迭代器-------");
Iterator<String> iterator=hashSet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
System.out.println(hashSet.contains("张三"));
System.out.println(hashSet.isEmpty());
}
}
demo2:
package com.study.Set;
/*
* hashset存储特点
* 1.根据hashCode计算保存的位置,如果位置为空,直接保存,若不为空,进行第二步
* 再执行equals方法,如果equals为true,则认为是重复,否则形成链表
* */
import java.util.HashSet;
import java.util.Iterator;
public class HashSetdemo2 {
public static void main(String[] args) {
HashSet<Person> hashSet=new HashSet<>();
Person p1=new Person("张三", 20);
Person p2=new Person("李四", 20);
Person p3=new Person("王五", 20);
hashSet.add(p1);
hashSet.add(p2);
hashSet.add(p3);
//hashSet.add(new Person("张三", 20));
//重复元素不能添加
//根据我们重写的hashcode和equals方法
System.out.println(hashSet.size());
System.out.println(hashSet.toString());
// hashSet.remove(p1);
// hashSet.remove(new Person("王五", 20));//同理
// System.out.println(hashSet.size());
System.out.println("-------1增强for-------");
for (Person person : hashSet) {
System.out.println(person);
}
System.out.println("-------2迭代器-------");
Iterator<Person> it=hashSet.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
System.out.println(hashSet.contains(p1));
System.out.println(hashSet.isEmpty());
}
}
Person类
package com.study.Set;
public class Person {
private String name;
private int age;
public Person() {
// TODO Auto-generated constructor stub
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the age
*/
public int getAge() {
return age;
}
/**
* @param age the age to set
*/
public void setAge(int age) {
this.age = age;
}
/* (non-Javadoc)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
// @Override
// public int hashCode() {
// int n1=this.name.hashCode();
// int n2=this.age;
// return n1+n2;
// }
// @Override
// public boolean equals(Object obj) {
// //判断是否相等
// if (this==obj) {
// return true;
// }
// //判断是否为空
// if (obj==null) {
// return false;
// }
// //判断是否是相同类型
// if (obj instanceof Person) {
// Person p=(Person)obj;
// //比较属性
// if (this.name.equals(p.getName())&&this.age==p.getAge()) {
// return true;
// }
// }
// //不满足返回flase
// return false;
}
}
3.3TreeSet
特点
- 基于排列顺序实现元素不重复
- 实现SortedSet接口,对集合元素自动排序
- 元素对象的类型必须实现Comparable接口,指定排序规则
- 通过CompareTo方法确定是否为重复元素
存储结构:红黑树
增加,删除,遍历,判断同上
注意:再添加时要重写Comparable接口方法,告诉编辑器比较的规则,否则报错
@Override
public int compareTo(Person o) {
int n1=this.getName().compareTo(o.getName());
int n2=this.age-o.getAge();
return n1==0?n2:n1;//名字相同,用年龄比,反之
//先比名字,名字相同再比年龄
}
完整代码:
package com.study.Set;
import java.util.Iterator;
import java.util.TreeSet;
public class TreeSetdemo {
public static void main(String[] args) {
TreeSet<Person> treeSet=new TreeSet<>();
Person p1=new Person("xyz", 20);
Person p2=new Person("abc", 21);
Person p3=new Person("hello", 20);
Person p4=new Person("hello", 21);
treeSet.add(p1);
treeSet.add(p2);
treeSet.add(p3);
treeSet.add(p4);
System.out.println(treeSet.size());
System.out.println(treeSet.toString());
// treeSet.remove(p1);
// System.out.println(treeSet.size());
System.out.println("-------1增强for-------");
for (Person person : treeSet) {
System.out.println(person);
}
System.out.println("-------2迭代器-------");
Iterator<Person> it=treeSet.iterator();
while (it.hasNext()) {
System.out.println(it.next());
}
System.out.println(treeSet.contains(p1));
System.out.println(treeSet.isEmpty());
}
}
//person其他同上,多了一个红黑树比较规则
@Override
public int compareTo(Person o) {
int n1=this.getName().compareTo(o.getName());
int n2=this.age-o.getAge();
return n1==0?n2:n1;//名字相同,用年龄比,反之
//先比名字,名字相同再比年龄
}
Treeset补充:
- Comparator 实现定制比较(比较器)直接再treeset集合创建时写
- Comparable 可比较的,要在具体的类里面写
package com.study.Set;
import java.util.Comparator;
import java.util.TreeSet;
public class TreeSetdemo3 {
public static void main(String[] args) {
TreeSet<String> treeSet=new TreeSet<>(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.add("helloworld");
treeSet.add("hello");
treeSet.add("world");
treeSet.add("java");
treeSet.add("hcq");
treeSet.add("YG");
treeSet.add("fuzhou");
treeSet.add("fint");
System.out.println(treeSet.toString());
}
}
4.Map集合
Map接口的特点:
- 用于存储任意键值对(key - value)
- 键:无序、无下标、不允许重复(唯一)
- 值:无序、无下标、允许重复
方法:
- V put(K key, V value) 将对象存到集合中,关联键值
- Object get(Object key) 根据键获得对应的值
- Set<K> 返回所有的Key
- Collection<V> values() 返回包含所有值的Collection集合
- Set<Map.Entry<K, V>> 键值匹配的Set集合
使用:
package com.study.Map;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class demo1 {
public static void main(String[] args) {
//创建集合
Map<String, String> map=new HashMap<>();
//增加
map.put("cn", "中国");
map.put("uk", "英国");
map.put("usa", "美国");
//map.put("usa", "the usa");//键是唯一的,不可以重复,值可以重复,会替换掉相同建的值
System.out.println(map.size());
System.out.println(map.toString());
//删除
// map.remove("usa");
// System.out.println(map.toString());
//遍历【重点】
System.out.println("-----keyset()方法-----");
//将Map中所有的键存入到set集合中。因为set具备迭代器。
//所有可以迭代方式取出所有的键,再根据get方法。
//获取每一个键对应的值。 keySet():迭代后只能通过get()取key
Set<String> keyset=map.keySet();
for (String key : keyset) {
System.out.println(key+"---"+map.get(key));
}
System.out.println("-----entrySet()方法-----");
//entrySet实现了Set接口,里面存放的是键值对。一个K对应一个V
Set<Map.Entry<String, String>> entry=map.entrySet();
for (Map.Entry<String, String> entry1 : map.entrySet()) {
System.out.println(entry1.getKey()+"---"+entry1.getValue());
}
//判断
System.out.println(map.containsKey("cn"));
System.out.println(map.containsValue("泰国"));
}
}
4.1HashMap【重点】
存储结构:哈希表(数组+链表+红黑树)
使用key可使hashcode和equals作为重复
增、删、遍历、判断与上述一致
原码分析总结:
- HashMap刚创建时,table是null,节省空间,当添加第一个元素时,table容量调整为16
- 当元素个数大于阈值(16*0.75 = 12)时,会进行扩容,扩容后的大小为原来的两倍,目的是减少调整元素的个数
- jdk1.8 当每个链表长度 >8 ,并且数组元素个数 ≥64时,会调整成红黑树,目的是提高效率
- jdk1.8 当链表长度 <6 时 调整成链表
- jdk1.8 以前,链表时头插入,之后为尾插入
代码:
package com.study.Map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class HashMapDemo {
public static void main(String[] args) {
HashMap<Student, String> hashMap=new HashMap<>();
Student s1=new Student("张三",100);
Student s2=new Student("李四",101);
Student s3=new Student("王五",102);
hashMap.put(s1, "北京");
hashMap.put(s2, "上海");
hashMap.put(s3, "深圳");
hashMap.put(new Student("王五",102), "深圳");
//可以添加成功,这里new了一个新的key,所以添加成功
//要对key的值进行判断,值相同就是一个相同的key
//在student里面重写hashCode()和equals方法
//重写完成后就无法添加
System.out.println(hashMap.size());
System.out.println(hashMap.toString());
// hashMap.remove(s1);
// System.out.println(hashMap.size());
System.out.println("-----keyset()方法-----");
for (Student key : hashMap.keySet()) {
System.out.println(key.toString()+"---"+hashMap.get(key));
}
System.out.println("-----entrySet()方法-----");
for (Map.Entry<Student, String> key : hashMap.entrySet()) {
System.out.println(key.getKey()+"---"+hashMap.get(key));
}
System.out.println(hashMap.containsKey(s1));
System.out.println(hashMap.containsKey(new Student("王五",102)));
}
}
4.2TreeMap
实现了SortedMap接口(是map的子接口),可以对key自动排序
package com.study.Map;
import java.util.Comparator;
import java.util.TreeMap;
/*与treeset类似要定义比较规则
* Comparator 实现定制比较(比较器)直接再treeset集合创建时写
* Comparable 可比较的,要在具体的类里面写
* */
public class TreeMapDemo {
public static void main(String[] args) {
TreeMap< Student, String> treeMap=new TreeMap<>(new Comparator<Student>() {
@Override
public int compare(Student o1, Student o2) {
int n=o1.getStunum()-o2.getStunum();
return n;
}
});
Student s1=new Student("张三",100);
Student s2=new Student("李四",101);
Student s3=new Student("王五",102);
treeMap.put(s1, "北京");
treeMap.put(s2, "上海");
treeMap.put(s3, "深圳");
System.out.println(treeMap.size());
System.out.println(treeMap.toString());
//删除,遍历,判断与hashmap相同
}
}
5Collections工具类
概念:集合工具类,定义了除了存取以外的集合常用方法
直接二分查找int i = Collections.binarySearch(list, x);
成功返回索引
其他方法 : copy复制、reverse反转、shuffle打乱
package com.study.Collections;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
public class Demo {
public static void main(String[] args) {
List<Integer> list =new ArrayList<Integer>();
list.add(15);
list.add(20);
list.add(13);
list.add(19);
list.add(25);
list.add(9);
//sort排序
System.out.println("排序之前:"+list.toString());
Collections.sort(list);
System.out.println("排序之后:"+list.toString());
//binarySearch二分查找
int i=Collections.binarySearch(list, 13);//找到返回数组下标,没有返回负数
System.out.println(i);
//copy复制
List<Integer> dest=new ArrayList<>();
for(int k=0;k<list.size();k++) {
dest.add(0);
//遍历原数组长度,扩充复制体数组,使得复制体数组与原数组大小相同
}
Collections.copy(dest, list);//第一个空是复制到哪里,第二个是复制的数据来源
//注意:复制体数组要和原数组大小相等,才可以复制
//提示报错说明你没有给复制体数组设置大小
System.out.println("复制体数组:"+dest);
//reverse反转
Collections.reverse(list);
System.out.println(list);
//shuffle打乱
Collections.shuffle(list);
System.out.println(list);
//list转换成为数组
System.out.println("-----list转换成为数组-----");
Integer[] arr=list.toArray(new Integer[10]);
//list转换的数组长度与list相同
//也可以定义长度,超出的部分填充为null
//[19, 20, 15, 13, 25, 9, null, null, null, null]
System.out.println(arr.length);
System.out.println(Arrays.toString(arr));
//数组转换成集合
System.out.println("-----数组转换成集合-----");
String[] name= {"张三","李四","王五"};
List<String> list2=Arrays.asList(name);
//这个转换的集合是一个受限数组无法增加和修改
System.out.println(list2);
System.out.println("-----基本类型数组转换成集合-----");
//注意:基本类型数组转换成集合时,需要修改为包装类
Integer[] no= {100,200,300,400};
List<Integer> list3=Arrays.asList(no);
System.out.println(list3);
}
}