集合
概念:对象的容器,定义了对多个对象进行操作的常用方法。可实现数组的功能
和数组的区别
数组长度固定,集合长度不固定
数组可以存储基本类型和引用类型,集合只能存储引用类型
位置: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); } }