集合
概念:对象的容器,定义了对多个对象进行操作的常用方法。可实现数组的功能
和数组的区别
-
数组长度固定,集合长度不固定
-
数组可以存储基本类型和引用类型,集合只能存储引用类型
位置:java.util.*
Collection体系集合

Collection接口
练习一
package com.collection.demo01;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
/*
* Collection接口的使用
* 1.添加元素
* 2.删除元素
* 3.遍历元素
* 4.判断
* */
public class Demo01 {
public static void main(String[] args) {
//创建集合
Collection collection = new ArrayList();
//添加元素 add()
collection.add("苹果");
collection.add("西瓜");
collection.add("榴莲");
System.out.println("元素个数:" + collection.size());
System.out.println(collection); //相当于sout(collection.toString());
//删除元素 remove()
// collection.remove("榴莲");
// System.out.println("删除后"+collection.size());
// collection.clear();
// System.out.println("清除后"+collection.size());
//遍历元素
//1.使用增强for forEach 普通for不能用,因为没有下标
for (Object o : collection) {
System.out.println(o);
}
//2.使用迭代器 Iterator 专门用来遍历集合的一种方式
Iterator it = collection.iterator(); //Iterator遍历collection的迭代器 hasNext():有没有下一个元素 next():获取下一个元素 remove():删除当前元素
while (it.hasNext()) {
String s = (String) it.next();
System.out.println(s);
//collection.remove(s); //迭代时不能进行集合删除操作 会报异常:ConcurrentModificationException
//it.remove(); //使用迭代器的remove方法是可以的
}
System.out.println("元素个数" + collection.size());
//判断 contains() isEmpty()
System.out.println(collection.contains("西瓜"));
System.out.println(collection.isEmpty()); //判断元素是否为空
}
}
练习二
package com.collection.demo01;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
//Collection的使用:保存学生信息
public class Demo02 {
public static void main(String[] args) {
//新建一个Collection对象
Collection collection = new ArrayList();
//创建学生对象
Student s1 = new Student("Tom",1);
Student s2 = new Student("Jack",2);
Student s3 = new Student("Jack",3);
//1.添加学生数据
collection.add(s1);
collection.add(s2);
collection.add(s3);
collection.add(s3);
System.out.println("元素个数" + collection.size());
System.out.println(collection.toString());
//删除
collection.remove(s3); //只是把地址删除,堆里还留着
System.out.println("删除之后" + collection.size());
//1.增强for
for(Object o : collection) {
Student s = (Student)o;
System.out.println(s);
}
//2.迭代器
Iterator iterator = collection.iterator();
while(iterator.hasNext()) {
Student s = (Student)iterator.next();
System.out.println(s);
}
//判断
System.out.println(collection.contains(new Student("Tom",1))); //false 并不是原有的Tom
System.out.println(collection.contains(s1));
System.out.println(collection.isEmpty());
}
}
package com.collection.demo01;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(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 "名字:" + name +
", 年龄:" + age +
"\t";
}
}
List集合
- 特点:有序、有下标、元素可以重复
List方法使用
案例1:
package com.collection.demo02;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
/*
* List接口的使用
* 1.有序、有下标
* 2.可重复
* */
public class Demo01 {
public static void main(String[] args) {
//创建集合对象
List list = new ArrayList();
//1.添加元素
list.add("iPhone");
list.add("xiaomi");
list.add(0,"HUAWEI"); //表示在角标为0位置添加
System.out.println("元素个数"+list.size());
System.out.println(list);
//删除元素
list.remove(0); //把第一个元素删除
System.out.println("元素个数"+list.size());
System.out.println(list);
//遍历
//1.for
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//2.forEach
for(Object o : list) {
System.out.println(o);
}
//3.迭代器
Iterator iterator = list.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
//4.列表迭代器
/*
* 和Iterator的区别:
* ListIterator可以向前向后遍历,可以增、删、改元素
* */
//4.1从前往后
ListIterator lit = list.listIterator();
while (lit.hasNext()) {
System.out.println(lit.nextIndex()+ ":" +lit.next());
}
//4.2从后往前
while (lit.hasPrevious()) {
System.out.println(lit.previousIndex()+ ":" +lit.previous());
}
//判断
System.out.println(list.contains("xiaomi"));
System.out.println(list.isEmpty());
//获取位置
System.out.println(list.indexOf("xiaomi"));
}
}
案例2:
package com.collection.demo02;
import java.util.ArrayList;
import java.util.List;
/*
* List的使用
*
* */
public class demo02 {
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);
//删除
//list.remove(20); //默认删除角标是20的元素
//System.out.println("删除数据后"+list.size()); //报错:IndexOutOfBoundsException
//解决方法
// list.remove(0);
// list.remove((Object)20);
// list.remove(new Integer(20));
//补充方法subList 截取集合 返回子集合
List subList = list.subList(1, 3); //含头不含尾
System.out.println(subList);
}
}
List实现类
ArrayList
-
ArrayList【重点】:
-
数组结构实现,内部有数组,查询快、增删满
-
JDK1.2版本引入,运行效率快、线程不安全
源码分析:
默认容量DEFAULT_CAPACITY = 10
注意:如果没有向集合中添加任何元素时,容量0,添加任意一个元素,容量为10,超过10,扩容,每次扩容大小是原来的1.5倍
存放元素数组:elementData
size 实际元素个数
add()
-
package com.collection.demo02;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.ListIterator;
/*
* ArrayList的使用
* 存储结构:查找遍历速度快,增删慢
*
* */
public class Demo03 {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList<>();
//添加元素
Student s1 = new Student("Tom",1);
Student s2 = new Student("Jack",2);
Student s3 = new Student("Jerry",3);
arrayList.add(s1);
arrayList.add(s2);
arrayList.add(s3);
System.out.println("元素个数"+arrayList.size());
System.out.println(arrayList);
//删除元素
// arrayList.remove(s1);
// System.out.println("删除之后"+arrayList.size());
// System.out.println(arrayList);
// arrayList.remove(new Student("Tom",1)); //remove其实调用了equals(this == obj)方法
//想要实现这行代码,解决方案:重写equals
//遍历元素【重点】
//1.for
for (int i = 0; i < arrayList.size(); i++) {
System.out.println(arrayList.get(i));
}
//2.forEach
for(Object o: arrayList) {
System.out.println(o);
}
//迭代器
Iterator it = arrayList.iterator();
while(it.hasNext()) {
Student s = (Student)it.next();
System.out.println(s);
}
//列表迭代器
//正序
ListIterator lit = arrayList.listIterator();
while(lit.hasNext()){
Student s = (Student)lit.next();
System.out.println(s);
}
//倒序
while(lit.hasPrevious()){
Student s = (Student)lit.previous();
System.out.println(s);
}
//判断
System.out.println(arrayList.contains(s1));
System.out.println(arrayList.contains(new Student("Tom",1)));
System.out.println(arrayList.isEmpty());
//查找
System.out.println(arrayList.indexOf(s1));
System.out.println(arrayList.indexOf(new Student("Tom",1)));
}
}
Vector
-
Vector:
-
数组结构实现,查询快、增删慢
-
1.0版本,运行效率满,线程安全
-
package com.collection.demo02;
import java.util.Enumeration;
import java.util.Vector;
public class Demo04 {
public static void main(String[] args) {
//创建集合
Vector vector = new Vector();
//添加元素
vector.add("草莓");
vector.add("西瓜");
vector.add("苹果");
System.out.println(vector);
//删除元素
// vector.remove(1);
// vector.remove("苹果");
// System.out.println(vector);
//遍历元素
//1.for
for(int i = 0; i < vector.size();i++){
System.out.println(vector.get(i));
}
//2.foreach
for (Object o : vector) {
System.out.println(o);
}
//3.使用枚举器
Enumeration enumeration = vector.elements();
while(enumeration.hasMoreElements()) {
System.out.println(enumeration.nextElement());
}
//4.判断
System.out.println(vector.contains("草莓"));
System.out.println(vector.isEmpty());
//5.其他方法:firstElement,lastElement,elementAt
}
}
LinkedList
-
LinkedList:
- 链表结构实现,双向链表,增删快,查询慢
package com.collection.demo02;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.ListIterator;
public class Demo05 {
public static void main(String[] args) {
//创建集合
LinkedList list = new LinkedList();
Student s1 = new Student("Tom",1);
Student s2 = new Student("Tom",2);
Student s3 = new Student("Tom",3);
//添加元素
list.add(s1);
list.add(s2);
list.add(s3);
//删除元素
// list.remove(s1);
// list.remove(1);
// list.clear();
//遍历元素
//1.for
for(int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//2.forEach
for (Object o : list) {
System.out.println(o);
}
//3.迭代器
Iterator it = list.iterator();
while(it.hasNext()) {
System.out.println(it.next());
}
//4.使用列表迭代器
//正序
ListIterator lit = list.listIterator();
while(lit.hasNext()) {
System.out.println(lit.next());
}
//倒序
while(lit.hasPrevious()) {
System.out.println(lit.previous());
}
//判断
System.out.println(list.contains(s1));
System.out.println(list.isEmpty());
//查找
System.out.println(list.indexOf(s2));
}
}
ArrayList和LinkedList区别
ArrayList:必须开辟连续空间,查询快,增删慢
LinkedList:无需开辟连续空间,查询慢,增删快

泛型
泛型类
package com.collection.generic;
/*
* 泛型类
* 语法:类名<T>
* T是类型占位符,表示一种引用类型,如果编写多个用","隔开
*
*
* */
public class MyGeneric<T> {
//使用泛型
//1.创建变量
T t;
//2.添加方法 泛型作为方法的参数
public void show(T t) {
//不能实例化 new T()
System.out.println(t);
}
//3.泛型作为方法的返回值
public T getT() {
return t;
}
}
package com.collection.generic;
public class TestGeneric {
public static void main(String[] args) {
//使用泛型类创建对象 占位符T只能是引用类型
MyGeneric<String> myGeneric = new MyGeneric<>(); //后面的<>里可写可不写 1.7之前一定要写
myGeneric.t = "hello";
myGeneric.show("Welcome");
String s = myGeneric.getT();
MyGeneric<Integer> myGeneric2 = new MyGeneric<>();
myGeneric2.t = 100;
myGeneric2.show(200);
Integer i = myGeneric2.getT();
//不同泛型类型对象之间不能相互赋值
//MyGeneric<String> myGeneric3 = myGeneric2;
MyGeneric<String> myGeneric3 = myGeneric;
myGeneric3.show("都是String泛型,就可以直接赋值");
}
}
泛型接口
package com.collection.generic;
public class MyInterfaceImpl implements MyInterface<String> {
@Override
public String server(String s) {
System.out.println(s);
return s;
}
}
package com.collection.generic;
//接口的实现类也不确定类型,就将实现类变成泛型 实现类是什么类型 接口就也是这个类型
public class MyInterfaceImpl2<T> implements MyInterface<T> {
@Override
public T server(T t) {
System.out.println(t);
return t;
}
}
package com.collection.generic;
public class Test1 {
public static void main(String[] args) {
MyInterfaceImpl impl = new MyInterfaceImpl();
String str = impl.server("接口实现类重写的方法");
System.out.println(str);
MyInterfaceImpl2<Integer> impl2 = new MyInterfaceImpl2<>();
impl2.server(100);
}
}
泛型方法
package com.collection.generic;
/*
* 泛型方法
* 语法:<T> 方法的返回值类型
* */
public class MyGenericMethod {
//泛型方法
public <T> void show(T t) {
System.out.println("MyGenericsMethod:"+t.getClass().getName());
}
}
package com.collection.generic;
public class Test2 {
public static void main(String[] args) {
//泛型方法
MyGenericMethod myGenericMethod = new MyGenericMethod();
myGenericMethod.show("Welcome"); //T的类型跟你在这行传递的数据而确定
myGenericMethod.show(200);
myGenericMethod.show(3.14);
}
}
泛型好处
-
提高代码的重用性,没学泛型之前要方法的重载才能用同一个方法输出不同类型的对象
-
防止类型转换异常,提高代码的安全性
泛型集合
-
概念:参数化类型、类型安全的集合、强制集合元素类型必须一致
-
特点:
-
编译时即可检查,而非运行时抛出异常
-
访问时,不必类型转换(拆箱)
-
不同泛型之间的引用不能相互赋值,泛型不存在多态
-
package com.collection.generic;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(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 boolean equals(Object obj) {
if(this == obj){
return true;
}
if(obj == null){
return false;
}
if(obj instanceof Student){
Student s = (Student)obj;
if(s.getName().equals(this.name)&&s.getAge() == this.age){
return true;
}
}
return false;
}
@Override
public String toString() {
return "名字:" + name +
", 年龄:" + age +
"\t";
}
}
package com.collection.generic;
import java.util.ArrayList;
import java.util.Iterator;
public class Demo {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
for (String s : list) {
System.out.println(s);
}
ArrayList<Student> list1 = new ArrayList<>();
Student s1 = new Student("Tom", 1);
Student s2 = new Student("Jack", 2);
Student s3 = new Student("Jane", 3);
list1.add(s1);
list1.add(s2);
list1.add(s3);
Iterator<Student> iterator = list1.iterator();
while (iterator.hasNext()) {
Student student = iterator.next();
System.out.println(student);
}
}
}
set集合
-
特点:无序、无下标、元素不可重复
-
方法:全部继承Collection方法
package com.collection.demo04;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/*
* Set接口的使用
*特点:无序、没有下标、不能重复
* */
public class Demo01 {
public static void main(String[] args) {
//创建集合
Set<String> set = new HashSet<String>();
//1.添加数据
set.add("iPhone");
set.add("iPad");
set.add("Mac");
set.add("Mac"); //没有添加进来,和上面的重复了
System.out.println("元素个数"+set.size());
//2.删除数据
// set.remove("iPhone"); //不能通过角标删除
// System.out.println("删除后元素个数"+set.size());
// set.clear();
// System.out.println("清除后元素个数"+set.size());
//3.遍历【重点】
//3.1 增强for
for (String s : set) {
System.out.println(s);
}
//3.2 迭代器
Iterator<String> iterator = set.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
//4.判断
System.out.println(set.contains("iPhone"));
System.out.println(set.isEmpty());
}
}
Set实现类
HashSet【重点】
-
基于HashCode计算元素存放位置
-
当存入元素的哈希码相同时,会调用equals进行确认,结果为true,则拒绝后者存入
案例1:
package com.collection.demo04;
import java.util.HashSet;
import java.util.Iterator;
/*
* HashSet集合的使用
* 存储结构:哈希表(数组+链表+红黑树(1.8引入))
*
* */
public class Demo02 {
public static void main(String[] args) {
//创建集合
HashSet<String> hashSet = new HashSet<String>();
//添加元素
hashSet.add("米法");
hashSet.add("力巴尔");
hashSet.add("乌尔波扎");
hashSet.add("达尔克尔");
hashSet.add("达尔克尔"); //重复的添加不进去
System.out.println("英杰个数" + hashSet.size());
//删除数据
// hashSet.remove("米法");
// hashSet.clear();
// System.out.println("英杰个数"+hashSet.size());
//3.遍历
//3.1 增强for
for (String s : hashSet) {
System.out.println(s);
}
//3.2 使用迭代器
Iterator<String> iterator = hashSet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
//4.判断
System.out.println(hashSet.contains("林克"));
hashSet.clear();
System.out.println(hashSet.isEmpty());
}
}
案例2:
package com.collection.demo04;
import com.collection.demo02.Student;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
//重写toString方法不然默认打印哈希值
return "名字:"+name+";年龄:"+age;
}
@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(p.getName().equals(this.name)&&p.getAge() == this.age){
return true;
}
}
return false;
}
}
package com.collection.demo04;
import java.util.HashSet;
import java.util.Iterator;
public class Demo03 {
public static void main(String[] args) {
//创建对象
HashSet<Person> person = new HashSet<>();
//1.添加对象
Person p1 = new Person("Tom", 1);
Person p2 = new Person("Jack", 2);
Person p3 = new Person("Jane", 3);
person.add(p1);
person.add(p2);
person.add(p3);
person.add(p3); //重复的不能添加
person.add(new Person("Tom", 1)); //这样会添加进去 想让它p1是重复的 就重写hashCode() equals()
/*
* 存储过程
* 根据hashCode计算保存的位置
* 位置为空:保存
* 位置不为空->
* 执行equals方法
* 如果equals方法为true:认为重复
* false:形成链表
* */
System.out.println("元素个数" + person.size());
//删除元素
person.remove(p1);
System.out.println("元素个数" + person.size());
//遍历
//1.增强for
for (Person person1 : person) {
System.out.println(person1);
}
//2.迭代器
Iterator<Person> iterator = person.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
//判断
System.out.println(person.contains(p1));
System.out.println(person.contains(new Person("Jack", 2))); //true 因为重写了hashCode equals
}
}
HashSet补充
以前系统重写的hashCode()出现31:
-
31是一个质数,可以生成均匀的数据,减少散列冲突
-
提升执行效率 31*i = (i << 5) - i;位运算快
TreeSet
-
基于排列顺序实现元素不重复 二叉查找树
-
实现了SortedSet接口,对集合自动排序
-
元素对象的类型必须实现Comparable接口,指定排序规则
-
通过CompareTo方法确定是否为重复元素
案例1:
package com.collection.demo04;
import java.util.Iterator;
import java.util.TreeSet;
/*
*TreeSet的使用
*存储结构:红黑树
* */
public class Demo04 {
public static void main(String[] args) {
//创建集合
TreeSet<String> treeSet = new TreeSet<String>();
//1.添加元素
treeSet.add("xyz");
treeSet.add("abc");
treeSet.add("Hello");
treeSet.add("xyz"); //重复的添加不来
System.out.println("元素个数" + treeSet.size());
//2.删除
treeSet.remove("xyz");
System.out.println("删除后元素个数" + treeSet.size());
//3.遍历
//3.1增强for
for (String s : treeSet) {
System.out.println(s);
}
//3.2迭代器
Iterator<String> iterator = treeSet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
//4.判断
System.out.println(treeSet.contains("abc"));
}
}
案例2:
package com.collection.demo04;
import com.collection.demo02.Student;
public class Person implements Comparable<Person> {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
//重写toString方法不然默认打印哈希值
return "名字:"+name+";年龄:"+age;
}
@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(p.getName().equals(this.name)&&p.getAge() == this.age){
return true;
}
}
return false;
}
//先按姓名比,再按年龄比
@Override
public int compareTo(Person o) {
int n1 = this.getName().compareTo(o.getName());
int n2 = this.getAge() - o.getAge();
return n1 == 0 ? n2: n1;
}
}
package com.collection.demo04;
import java.util.Iterator;
import java.util.TreeSet;
/*
* 使用TreeSet保存数据
* 存储结构:红黑树
*要求:元素必须要实现Comparable接口,重写compareTo方法,compareTo返回值0,认为重复
* */
public class Demo05 {
public static void main(String[] args) {
//创建集合
TreeSet<Person> treeSet = new TreeSet<Person>();
//添加元素
Person p1 = new Person("Tom", 1);
Person p2 = new Person("Jack", 1);
Person p3 = new Person("Jane", 1);
treeSet.add(p1);
treeSet.add(p2);
treeSet.add(p3);
treeSet.add(new Person("Jack", 2));
System.out.println("元素个数" + treeSet.size());
System.out.println(treeSet);
//报错:Person cannot be cast to java.lang.Comparable
//二叉查找树放元素是小在左、大在右,我们并没有对Person类进行说明怎么比,就报错
//删除
// treeSet.remove(p1);
// System.out.println(treeSet.size());
// treeSet.remove(new Person("Jack", 1)); //这样也能删除
//遍历
//增强for
for (Person person : treeSet) {
System.out.println(person);
}
//迭代器
Iterator<Person> iterator = treeSet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
//判断
System.out.println(treeSet.contains(new Person("Tom", 1))); //true
}
}
Comparator接口
package com.collection.demo04;
import java.util.Comparator;
import java.util.TreeSet;
/*
* TreeSet的使用
* Comparator:实现定制比较(比较器)
* Comparable:可比较的
* */
public class Demo06 {
public static void main(String[] args) {
//创建集合
TreeSet<Person> persons = new TreeSet<>(new Comparator<Person>(){
//Comparator是一个接口不能直接new来实例化,这里我们使用匿名内部类
@Override
public int compare(Person o1, Person o2) {
int n1 = o1.getAge() - o2.getAge();
int n2 = o1.getName().compareTo(o2.getName());
return n1 == 0 ? n2:n1;
}
});
//添加元素
Person p1 = new Person("Tom", 1);
Person p2 = new Person("Jack", 2);
Person p3 = new Person("Jane", 3);
persons.add(p1);
persons.add(p2);
persons.add(p3);
System.out.println(persons);
}
}
案例:
package com.collection.demo04;
import java.util.Comparator;
import java.util.TreeSet;
/*
* 要求:使用TreeSet集合实现字符串长度进行排序
* Comparator接口进行定制比较
* */
public class Demo07 {
public static void main(String[] args) {
//创建集合,并指定规则
TreeSet<String> set = new TreeSet<String>(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;
}
});
//添加数据
set.add("a");
set.add("z");
set.add("ab");
set.add("bbc");
set.add("abc");
set.add("b");
System.out.println(set);
}
}
Map体系集合
Map接口的特点:
-
用于存储任意键值对(Key-Value)
-
键:无序、无下标、不允许重复
-
值:无序、无下标、允许重复

package com.collection.map;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/*
* Map接口的使用
* 特点:存储键值对 键不能重复值可以重复 无序
*
* */
public class Demo01 {
public static void main(String[] args) {
//创建集合
Map<String, String> map = new HashMap<>();
//1.添加元素
map.put("cn","中国");
map.put("uk","英国");
map.put("usa","美国");
map.put("cn","China");
System.out.println("元素个数"+map.size()); //还是3个
System.out.println(map); //打印出来发现,cn的value是China,把中国替换了
//2/删除
// map.remove("usa"); //通过key来删除
// System.out.println("删除后"+map.size());
//3.遍历
//3.1使用keySet()
Set<String> keySet = map.keySet(); //变成Set集合
for (String key : keySet) { //可以和上一行合并for(String key: map.keySet())
System.out.println(key+":"+map.get(key)); //通过key获得value
}
//3.2使用entrySet方法 效率高于keySet()
map.entrySet();
Set<Map.Entry<String, String>> entrySet = map.entrySet();
for (Map.Entry<String, String> entry : entrySet) { //同样可以和上一行合并for(Map.Entry<String,String> entry : Map.entrySet())
System.out.println(entry.getKey()+":"+entry.getValue());
}
//4.判断
System.out.println(map.containsKey("cn"));
System.out.println(map.containsValue("北京"));
}
}
Map实现类
HashMap 【重点】
和HashSet的关系,HashSet用的就是HashMap,add调用了put
线程不安全,运行效率快允许null作为key或者value
package com.collection.map;
import java.util.HashMap;
import java.util.Map;
/*
* HashMap集合的使用
* 存储结构:哈希表(数组+链表+红黑树)
* 使用key的hashCode和equals作为依据判断重复
* */
public class Demo02 {
public static void main(String[] args) {
//创建集合
HashMap<Student, String> students = new HashMap<Student, String>();
//1.添加元素
Student s1 = new Student("孙悟空", 1);
Student s2 = new Student("猪八戒",2);
Student s3 = new Student("沙和尚", 3);
students.put(s1,"花果山");
students.put(s2,"高老庄");
students.put(s3,"河");
students.put(s3,"流沙河"); //不能加进来,key不能重复 ,但是会把之前value替换
students.put(new Student("沙和尚", 3),"取经路上"); //可以加进来,new的和s3在堆里面地址不同 除非重写hashCode 和 equals, 可以alt+insert直接生成重写的这里不赘述
System.out.println("元素个数"+students.size());
System.out.println(students);
//2.删除
students.remove(s1); //通过key删除
//3.遍历
//3.1 keySet
for(Student key : students.keySet()) {
System.out.println(key+" "+students.get(key));
}
//3.2 entrySet
for(Map.Entry<Student, String> entry : students.entrySet()) {
System.out.println(entry.getKey()+" "+entry.getValue());
}
//判断
System.out.println(students.containsKey(s1));
System.out.println(students.containsKey(new Student("猪八戒", 2))); //没重写hashCode equals 堆里面还没有这个 false 如果重写了和s2一样,true
System.out.println(students.containsValue("花果山"));
}
}
HashMap源码总结
-
HashMap刚创建时,table是null,为了节省空间,当添加第一个元素时,table容量调整为16
-
当元素个数大于阈值(16*0.75)时,会进行扩容,扩容后大小为原来的2倍。目的是减少调整元素的个数
-
jdk1.8当每个链表长度大于8,并且数组元素个数大于等于64,会调整为红黑树,目的是提高执行效率
-
jdk1.8 当链表长度小于6时,调整成链表
-
jdk1.8 以前,链表头插入,1.8以后,尾插入
Hashtable和Properties
线程安全,运行效率慢,不允许null作为key或者是value
Properties:Hashtable的子类,要求key和value都是String,通常用于配置文件的读取
TreeMap
和TreeSet的关系,TreeSet用的就是TreeMap,add调用了put
实现了SortedMap接口,可以对key自动排序
package com.collection.map;
import java.util.Map;
import java.util.TreeMap;
/*
* TreeMap的使用
* 存储结构:红黑树
*
* */
public class Demo03 {
public static void main(String[] args) {
//创建集合
TreeMap<Student, String> students = new TreeMap<Student, String>();
//添加元素
Student s1 = new Student("孙悟空", 1);
Student s2 = new Student("猪八戒",2);
Student s3 = new Student("沙和尚", 3);
students.put(s1,"花果山");
students.put(s2,"高老庄");
students.put(s3,"流沙河");
students.put(new Student("沙和尚", 3),"取经路上"); //不能加进来,但是把value替换了
System.out.println("元素个数"+students.size());
System.out.println(students); //出现类型转换异常 Student cannot be cast to java.lang.Comparable 去Student类里实现Comparable接口并创建比较规则
//2.删除
// students.remove(s1);
// students.remove(new Student("猪八戒", 2)); //能删除,把他当作s2
// System.out.println(students.size());
//3.遍历
//3.1使用keySet
for (Student key: students.keySet()) {
System.out.println(key+":"+students.get(key));
}
//3.2使用entrySet
for(Map.Entry<Student, String> entry: students.entrySet()) {
System.out.println(entry.getKey()+":"+entry.getValue());
}
//4.判断
System.out.println(students.containsKey(new Student("猪八戒", 2))); //true
}
}
Collections工具类
package com.collection.demo05;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
/*
* Collections工具类的使用
*
* */
public class Demo01 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<Integer>();
list.add(38);
list.add(134);
list.add(4);
list.add(115);
list.add(35);
System.out.println("排序前"+list);
//sort排序
Collections.sort(list);
System.out.println("排序后"+list);
//binarySearch 二分查找
int i = Collections.binarySearch(list, 38);// 返回2,第三个元素
int j = Collections.binarySearch(list, 0);// 返回负数 表示不存在
System.out.println(i +" "+j);
//copy 复制
// List<Integer> dest= new ArrayList<>();
// Collections.copy(dest, list);
// System.out.println(dest); //异常:下标越界 copy方法要求两个集合大小相同
//解决方式
List<Integer> dest = new ArrayList<>();
for(int k = 0; k < list.size(); k++) {
dest.add(0);
} //给dest的元素和list一样多且都初始化为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 转成 数组
Integer[] arr = list.toArray(new Integer[list.size()]);
//new Integer[a] a<list.size()就自动把 a = list.size(), a > list.size() a多的就是null null...
System.out.println(arr.length);
System.out.println(Arrays.toString(arr));
//数组转成list 转后的集合是受限集合,不能对集合的元素进行修改
String[] names = {"Tom","Jerry","Jack","Mike","Bob"};
List<String> list2 = Arrays.asList(names);
System.out.println(list2);
//把基本类型数组转成集合,需要修改为包装类
int[] nums = {1,2,3,4,5};
List<int[]> list3 = Arrays.asList(nums); //不好,用下面的
System.out.println(list3);
Integer[] num = {1,2,3,4,5};
List<Integer> list4 = Arrays.asList(num);
System.out.println(list4);
}
}