集合
◆ 集合的概念:什么是集合?
对象的容器,定义了对多个对象进行操作的常用方法。可以实现数组的功能。
◆ 和数组的区别:
-
数组长度固定,集合长度不固定
-
数组可以存储基本类型和引用类型,集合只能存储引用类型
◆ 位置
Java.util.*(所有的类都在这个包里面)
Collection体系集合
◆ Collection父接口
特点:代表一组任意类型对象,无序、无下标、不能重复
方法:(列出一些)
-
boolean add(Object obj); //添加一个对象
-
boolean addAll(Collection c); //将一个集合中的所有对象添加到此集合
-
void clear(); //清空此集合中的所有对象
-
boolean contains(Object o); //检查此集合中是否包含o对象
-
boolean equals(Object o); //比较此集合是否与指定对象相等
-
boolean isEmpty(); //判断此集合是否为空
-
Iterator<E> iterator(); //返回在此集合的元素上进行迭代的迭代器(专门用来遍历集合的一种方式)
-
boolean remove(Object o); //在此集合中移除o对象
-
int size(); //返回此集合中的元素个数
-
Object[] toArray(); //将此集合转成数组
List子接口
◆ 特点:
有序、有下标、元素可以重复
◆ 方法:(列出一些)
-
void add(int index,Object o); //在index位置插入对象o
-
boolean addAll(int index,Collection c); //将一个集合中的元素添加到此集合中的index位置
-
Object get(int index); //返回集合中指定位置的元素
-
List subList(int fromIndex,int toIndex); //返回fromIndex和toIndex之间的集合元素
List实现类
ArrayList
◆ ArrayList【重点】:
-
数组结构实现,查询快、增删慢
-
JDK1.2版本,运行效率快,线程不安全
-
源码分析:
1)默认容量大小:int DEFAULT_CAPACITY = 10
注意:如果没有向集合中添加任何元素时,容量为0,添加一个元素之后,容量为10,填满之后就扩容(每次扩容,大小都为原来的1.5倍)
2)存放元素的数组:Object[] elementData
3)实际元素个数:int size
4)添加元素:add();
public boolean add(E e) { ensureCapacityInternal(size + 1); // Increments modCount!! elementData[size++] = e; return true; } private void ensureCapacityInternal(int minCapacity) { ensureExplicitCapacity(calculateCapacity(elementData, minCapacity)); } private void ensureExplicitCapacity(int minCapacity) { modCount++; // overflow-conscious code if (minCapacity - elementData.length > 0) grow(minCapacity); } private void grow(int minCapacity) { // overflow-conscious code int oldCapacity = elementData.length; int newCapacity = oldCapacity + (oldCapacity >> 1); if (newCapacity - minCapacity < 0) newCapacity = minCapacity; if (newCapacity - MAX_ARRAY_SIZE > 0) newCapacity = hugeCapacity(minCapacity); // minCapacity is usually close to size, so this is a win: elementData = Arrays.copyOf(elementData, newCapacity); }
/** * ArrayList的使用 * 存储结构:数组,查找遍历速度快,增删慢 */ public class ListArrayList { public static void main(String[] args) { //创建集合 size 0 容量 0,扩容(每次扩容,大小都为原来的1.5倍) ArrayList arrayList = new ArrayList<>(); //1. 添加元素 Student02 s1 = new Student02("刘德华",21); Student02 s2 = new Student02("郭富城",20); Student02 s3 = new Student02("黎明",25); Student02 s4 = new Student02("张学友",23); arrayList.add(s1); arrayList.add(s2); arrayList.add(s3); arrayList.add(s4); System.out.println("元素个数:"+arrayList.size()); System.out.println(arrayList); //2. 删除元素 //arrayList.remove(s1); //删除时,想要通过new一个对象删除,就必须要重写equals();方法,因为new一个对象删除实际上是用了equals();方法 // arrayList.remove(new Student02("刘德华",21)); //equals(this==obj) // System.out.println("删除之后:"+arrayList.size()); // System.out.println(arrayList); //3. 遍历元素 //3.1 迭代器 System.out.println("----------使用迭代器-------------"); Iterator it = arrayList.iterator(); while (it.hasNext()) { System.out.println(it.next()); } //3.2 列表迭代器 System.out.println("----------使用列表迭代器从前往后-------------"); ListIterator lit= arrayList.listIterator(); while (lit.hasNext()) { Student02 s = (Student02) lit.next(); System.out.println(s); } System.out.println("----------使用列表迭代器从后往前-------------"); while (lit.hasPrevious()) { System.out.println(lit.previous()); } //4. 判断 contains(Object o);判断集合里有没有o对象 System.out.println(arrayList.contains(s1)); //这时候已经重写了equals();方法 System.out.println(arrayList.contains(new Student02("刘德华",21))); //5. 查找 System.out.println(arrayList.indexOf(new Student02("刘德华",21))); } }
public class Student02 { private String name; private int age; public Student02(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 "Student02{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public boolean equals(Object obj) { //1.判断是否是同一个对象 if (this==obj) { return true; } //2.判断是否为空 if (obj==null) { return false; } //3.判断是否是Student02类 if (obj instanceof Student02) { Student02 s = (Student02) obj; //4.比较属性 if (this.name.equals(s.getName())&&this.age==s.getAge()) { return true; } } //5.不满足条件返回false return false; } }
Vector
◆ Vector(现在的开发用的不是特别多):
-
数组结构实现,查询快、增删慢
-
JDK1.0版本,运行效率慢,线程安全
/** * Vector的使用 * 存储结构:数组 * 查询快、增删慢 */ public class ListVector { public static void main(String[] args) { //创建集合 Vector vector = new Vector<>(); //1. 添加元素 vector.add("草莓"); vector.add("木瓜"); vector.add("芒果"); vector.add("西瓜"); System.out.println("元素个数:"+vector.size()); System.out.println(vector); //2. 删除元素 //vector.remove(0); //vector.remove("木瓜"); //vector.clear(); // System.out.println("删除之后:"+vector.size()); // System.out.println(vector); //3. 遍历 //使用枚举器,JDK1.2之前遍历Vector用的是枚举器 Enumeration en = vector.elements(); while (en.hasMoreElements()) { String o = (String) en.nextElement(); System.out.println(o); } //4. 判断 System.out.println(vector.contains("木瓜")); System.out.println(vector.isEmpty()); //5. 其他的方法 System.out.println(vector.firstElement()); System.out.println(vector.lastElement()); System.out.println(vector.elementAt(2)); } }
LinkedList
◆ LinkedList:
-
链表结构实现(双向链表),增删快、查询慢
-
源码分析:
1)集合的大小:int size
2)链表的头节点:Node first
3)链表的尾结点:Node last
void linkLast(E e) { final Node<E> l = last; final Node<E> newNode = new Node<>(l, e, null); last = newNode; if (l == null) first = newNode; else l.next = newNode; size++; modCount++; } private static class Node<E> { E item; Node<E> next; Node<E> prev; Node(Node<E> prev, E element, Node<E> next) { this.item = element; this.next = next; this.prev = prev; } }
/** * LinkedList的使用 * 存储结构:双向链表 */ public class ListLinkedList { public static void main(String[] args) { //创建集合 LinkedList linkedList = new LinkedList<>(); //1. 添加元素 Student02 s1 = new Student02("张三丰",20); Student02 s2 = new Student02("令狐冲",22); Student02 s3 = new Student02("任我行",25); linkedList.add(s1); linkedList.add(s2); linkedList.add(s3); System.out.println("元素个数:"+linkedList.size()); System.out.println(linkedList); //2. 删除元素 //linkedList.remove(1); //linkedList.remove(s1); // linkedList.remove(new Student02("张三丰",20)); // System.out.println("删除之后:"+linkedList.size()); // System.out.println(linkedList); //3. 遍历 //3.1 使用for遍历 System.out.println("------------使用for遍历-----------"); for (int i = 0; i < linkedList.size(); i++) { System.out.println(linkedList.get(i)); } //3.2 使用增强for System.out.println("------------使用增强for-----------"); for (Object obj : linkedList) { Student02 s = (Student02) obj; System.out.println(s); } //3.3 使用迭代器 System.out.println("------------使用迭代器-----------"); Iterator it = linkedList.iterator(); while (it.hasNext()) { Student02 s = (Student02) it.next(); System.out.println(s); } //3.4 使用列表迭代器 System.out.println("------------使用列表迭代器从前往后-----------"); ListIterator lit = linkedList.listIterator(); while (lit.hasNext()) { Student02 s = (Student02) lit.next(); System.out.println(s); } System.out.println("------------使用列表迭代器从后往前-----------"); while (lit.hasPrevious()) { Student02 s = (Student02) lit.previous(); System.out.println(s); } //4. 判断 System.out.println(linkedList.contains(s1)); System.out.println(linkedList.isEmpty()); //5. 获取 System.out.println(linkedList.indexOf(s2)); } }
ArrayList和LinkedList的区别
泛型
◆ Java泛型是JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递
◆ 常见形式:泛型类、泛型接口、泛型方法
◆ 语法:<T,...> T称为类型占位符,表示一种引用类型
◆ 好处:
1)提高代码的重用性
2)防止类型转换异常,提高代码的安全性
泛型类
/** * 泛型类 * 语法:类名<T> * T是类型占位符,表示一种引用类型,如果编写多个,使用逗号隔开 */ public class MyGeneric<T> { //使用泛型T //1.创建变量 T t; //2.添加方法 public void show(T t) { //T t1 = new T(); 不能直接实例化,不知道T的类型,不保证能传过来的T的类型的构造方法能用,也不能保证传过来的类型一定有无参构造 System.out.println(t); } //3.使用泛型作为方法的返回值 public T getT() { return t; } } public class MyGenericTest { public static void main(String[] args) { //使用泛型类创建对象 //注意: //1. 泛型只用使用引用类型 //2. 不同泛型类型对象之间不能相互复制 MyGeneric<String> myGeneric = new MyGeneric<>(); myGeneric.t = "hello"; myGeneric.show("加油,同学!"); String str = myGeneric.getT(); System.out.println(myGeneric.t); System.out.println(str); MyGeneric<Integer> myGeneric2 = new MyGeneric<>(); myGeneric2.t = 100; myGeneric2.show(150); Integer integer = myGeneric2.getT(); System.out.println(myGeneric2.t); System.out.println(integer); //MyGeneric<String> myGeneric3 = myGeneric2; } }
泛型接口
/** * 泛型接口 * 语法:接口名<T> * 注意:不能使用泛型创建静态常量 */ public interface MyInterface<T> { String name = "张三"; T server(T t); } //泛型接口实现类,用之前确定类型,比如此实现类是String类型 public class MyInterfaceImpl implements MyInterface<String>{ @Override public String server(String s) { System.out.println(s); return s; } } //泛型接口实现类,用的时候确定类型,比如此类还没确定,但是测试类new的时候确定类型 public class MyInterfaceImpl2<T> implements MyInterface<T>{ @Override public T server(T t) { System.out.println(t); return t; } } public class MyInterfaceImplTest { public static void main(String[] args) { //用之前确定类似,比如此类为String类 MyInterfaceImpl impl = new MyInterfaceImpl(); impl.server("xxxxx"); //用时确定类型,比如此类,用时为Integer类 MyInterfaceImpl2<Integer> impl2 = new MyInterfaceImpl2<>(); impl2.server(1000); } }
泛型方法
/** * 泛型方法 * 语法:<T> 返回值类型 */ public class MyGenericMethod { //泛型方法 public <T> T shou(T t) { System.out.println("泛型方法"+t); return t; } } public class MyGenericMethodTest { public static void main(String[] args) { MyGenericMethod myGenericMethod = new MyGenericMethod(); myGenericMethod.shou("fsd"); myGenericMethod.shou(200); myGenericMethod.shou(3.14); } }
泛型集合
◆ 概念:参数化类型、类型安全的集合,强制集合元素的类型必须一致
◆ 特点:
1)编译时即可检查,而非运行时抛出异常
2)访问时,不必类型转换(拆箱)
3)不同泛型之间引用不能相互赋值,泛型不存在多态
public class MyGenericJihe { public static void main(String[] args) { ArrayList<String> arrayList = new ArrayList<>(); arrayList.add("aaa"); arrayList.add("bbb"); arrayList.add("ccc"); for (String str : arrayList) { System.out.println(str); } ArrayList<Student02> arrayList2 = new ArrayList<>(); Student02 s1 = new Student02("刘德华",21); Student02 s2 = new Student02("郭富城",20); Student02 s3 = new Student02("黎明",25); Student02 s4 = new Student02("张学友",23); arrayList2.add(s1); arrayList2.add(s2); arrayList2.add(s3); arrayList2.add(s4); Iterator<Student02> it = arrayList2.iterator(); while (it.hasNext()) { Student02 s = it.next(); System.out.println(s); } //arrayList2 = arrayList; 泛型类型不同不能相互赋值 } }
Set子接口
◆ 特点:
无序、无下标、元素不可重复
◆ 方法:全部继承自Collection中的方法
Set实现类
HashSet
◆ HashSet【重点】:
-
基于HashCode实现元素不重复
-
当存入元素的哈希码相同时,会调用equals进行确认,如结果为true,则拒绝后者存入
/** * HashSet集合的使用 * 存储结构:哈希表(数组+链表(HDK1.7之前)+红黑树(JDK1.8之后)) */ public class Set_HashSet { public static void main(String[] args) { //创建集合 HashSet<String> hashSet = new HashSet<>(); //1. 添加元素 hashSet.add("张学友"); hashSet.add("郭富城"); hashSet.add("刘德华"); hashSet.add("黎明"); System.out.println("元素个数:"+hashSet.size()); System.out.println(hashSet); //2. 删除数据 // hashSet.remove("黎明"); // hashSet.clear(); // System.out.println("删除之后"+hashSet.size()); // System.out.println(hashSet); //3. 遍历 //3.1 增强for System.out.println("--------增强for---------"); for (String str : hashSet) { System.out.println(str); } //3.2 迭代器 System.out.println("--------迭代器---------"); Iterator<String> iterator = hashSet.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } //4. 判断 System.out.println(hashSet.contains("刘德华")); System.out.println(hashSet.contains("刘亦菲")); System.out.println(hashSet.isEmpty()); } } /** * HashSet集合的使用 * 存储结构:哈希表(数组+链表(HDK1.7之前)+红黑树(JDK1.8之后)) * 存储过程: * (1)根据hashcode计算保存的位置,如果此位置为空,则直接保存,如果不为空则执行第二步 * (2)再执行equals方法,如果equals方法为true,则认为是重复的,否则,形成链表 */ public class Set_HashSet02 { public static void main(String[] args) { //创建集合 HashSet<Set_Person02> person = new HashSet<>(); //1. 添加元素 Set_Person02 p1 = new Set_Person02("刘德华",15); Set_Person02 p2 = new Set_Person02("郭富城",35); Set_Person02 p3 = new Set_Person02("梁朝伟",25); person.add(p1); person.add(p2); person.add(p3); //person.add(p3); 重复不能添加 //person.add(new Set_Person02("郭富城",35)); new了一个对象,可以添加,但是名字和年龄一样 //要想要相同的元素不能添加,那就要重写hashcode和equals方法 person.add(new Set_Person02("郭富城",35)); System.out.println("元素个数:"+person.size()); System.out.println(person); //2. 删除元素 //person.remove(p1); // person.remove(new Set_Person02("刘德华",15)); // System.out.println("删除之后:"+person.size()); // System.out.println(person); //3. 遍历 //3.1 使用增强for System.out.println("-----------使用增强for-----------"); for (Set_Person02 p : person) { System.out.println(p); } //3.2 使用迭代器 System.out.println("-----------使用迭代器-----------"); Iterator<Set_Person02> it = person.iterator(); while (it.hasNext()) { System.out.println(it.next()); } //4. 判断 System.out.println(person.contains(p2)); System.out.println(person.contains(new Set_Person02("梁朝伟",25))); System.out.println(person.isEmpty()); } } //person类 public class Set_Person02 { private String name; private int age; public Set_Person02(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 "Set_Person02{" + "name='" + name + '\'' + ", age=" + age + '}'; } //一键生成 @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Set_Person02 person02 = (Set_Person02) o; return age == person02.age && Objects.equals(name, person02.name); } @Override public int hashCode() { return Objects.hash(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 Set_Person02) { // Set_Person02 person = (Set_Person02) obj; // if (this.name.equals(person.getName())&&this.age== person.getAge()) { // return true; // } // } // return false; // } }
TreeSet
◆ TreeSet:
-
基于排序顺序实现元素不重复
-
实现了SortedSet接口,对集合元素自动排序
-
元素对象的类型必须实现Comparable接口,指定排序规则
-
通过CompareTo方法确定是否为重复元素
/** * TreeSet的使用 * 存储结构:红黑树 */ public class Set_TreeSet01 { public static void main(String[] args) { //创建集合 TreeSet<String> treeSet = new TreeSet<>(); //1. 添加元素 treeSet.add("abc"); treeSet.add("hello"); treeSet.add("xyz"); treeSet.add("xyz"); System.out.println("元素个数:"+treeSet.size()); System.out.println(treeSet.toString()); //2. 删除元素 // treeSet.remove("xyz"); // System.out.println("删除之后:"+treeSet.size()); // System.out.println(treeSet.toString()); //3. 遍历 //3.1 增强for System.out.println("----------增强for---------"); for (String str : treeSet) { System.out.println(str); } //3.2 迭代器 System.out.println("----------迭代器--------"); Iterator<String> it = treeSet.iterator(); while (it.hasNext()) { System.out.println(it.next()); } //4. 判断 System.out.println(treeSet.contains("hello")); System.out.println(treeSet.isEmpty()); } } /** * TreeSet的使用 * 存储结构:红黑树 * 要求:元素必须要实现Comparable接口,compareTo()方法返回值为0,认为是重复元素 */ public class Set_TreeSet02 { public static void main(String[] args) { //创建集合 TreeSet<Set_Person02> person = new TreeSet<>(); //1. 添加元素 Set_Person02 p1 = new Set_Person02("xyz",15); Set_Person02 p2 = new Set_Person02("hello",35); Set_Person02 p3 = new Set_Person02("abc",25); Set_Person02 p4 = new Set_Person02("abc",15); person.add(p1); person.add(p2); person.add(p3); person.add(p4); System.out.println("元素个数:"+person.size()); System.out.println(person); //2. 删除 //person.remove(p1); // person.remove(new Set_Person02("abc",25)); // System.out.println("删除之后:"+person.size()); // System.out.println(person); //3. 遍历 //3.1 使用增强for System.out.println("-------------使用增强for--------------"); for (Set_Person02 s : person) { System.out.println(s); } //3.2 迭代器 System.out.println("-------------使用迭代器--------------"); Iterator<Set_Person02> iterator = person.iterator(); while (iterator.hasNext()) { System.out.println(iterator.next()); } //4. 判断 System.out.println(person.contains(new Set_Person02("abc",25))); System.out.println(person.isEmpty()); } } /** * TreeSet集合的使用 * comparator(接口):实现定制比较(比较器) * Comparable(接口):可比较的 */ public class Set_TreeSet03 { public static void main(String[] args) { //创建集合,并指定比较规则 TreeSet<Set_Person02> person = new TreeSet<>(new Comparator<Set_Person02>() { @Override public int compare(Set_Person02 o1, Set_Person02 o2) { int n1 = o1.getAge()-o2.getAge(); int n2 = o1.getName().compareTo(o2.getName()); return n1==0?n2:n1; } }); Set_Person02 p1 = new Set_Person02("xyz",15); Set_Person02 p2 = new Set_Person02("hello",35); Set_Person02 p3 = new Set_Person02("abc",25); Set_Person02 p4 = new Set_Person02("khs",25); person.add(p1); person.add(p2); person.add(p3); person.add(p4); System.out.println(person); } } /** * 案例: * 要求:使用TreeSet集合实现字符串按照长度进行排序 * hello world zhangsan huawei * Comparator接口实现定制比较规则 */ public class Set_TreeSet04 { 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("hello world"); treeSet.add("zhangsan"); treeSet.add("lisi"); treeSet.add("huawei"); treeSet.add("cat"); treeSet.add("xian"); System.out.println(treeSet.toString()); } }
Map集合
Map父接口
◆ 特点:存储一对数据(Key-Value),无序、无下标,键不可重复,值可重复
◆ 方法:
-
V put(K key,V value) //将对象存入到集合中,关联键值。key重复则覆盖原值
-
Object get(Object key) //根据键获取对应的值
-
Set<K> //返回所有key
-
Collection<V> values() //返回包含所有值的Collection集合
-
Set<Map.Entry<K,V>> //键值匹配的Set集合
/** * Map接口的使用 * 特点:(1)存储键值对 (2)键不能重复,值可以重复 (3)无序 */ public class Map01 { public static void main(String[] args) { //创建Map集合 Map<String, String> map = new HashMap<>(); //1. 添加元素 map.put("cn","中国"); map.put("uk","英国"); map.put("usa","美国"); System.out.println("元素个数:"+map.size()); System.out.println(map.toString()); //2. 删除元素 // map.remove("usa"); // System.out.println("删除之后:"+map.size()); // System.out.println(map.toString()); //3. 遍历 //3.1 使用keySet(); System.out.println("-----------使用keySet();---------"); //Set<String> keyset = map.keySet(); for (String key : map.keySet()) { System.out.println(key+"="+map.get(key)); } //3.2 使用entrySet(); System.out.println("-----------使用entrySet();---------"); Set<Map.Entry<String,String>> entries = map.entrySet(); for (Map.Entry<String,String> entry : entries) { System.out.println(entry.getKey()+"="+entry.getValue()); } } }
Map实现类
HashMap
◆ HashMap:
-
jdk1.2版本,线程不安全,运行效率快
-
允许用 null 作为 key 或是 value
◆ 存储结构:哈希表
◆ 重复依据:键的hashcode()方法和equals()方法
◆ 源码分析:
1 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 hashMap初始容量大小 2 static final int MAXIMUM_CAPACITY = 1 << 30; //hashmap的数组最大容量 3 static final float DEFAULT_LOAD_FACTOR = 0.75f; //默认加载因子 4 static final int TREEIFY_THRESHOLD = 8; //jdk1.8 当链表长度大于8时,调整为红黑树 5 static final int UNTREEIFY_THRESHOLD = 6; //jdk1.8 当链表长度小于6时,调整成链表 6 static final int MIN_TREEIFY_CAPACITY = 64; //jdk1.8 当当链表长度大于8时,并且集合元素个数大于等于64时,调整为红黑树 7 transient Node<K,V>[] table; //哈希表中的数组 8 size; //元素个数
◆ 源码分析总结:
-
HashMap刚创建时,table=null,size=0,为了节省空间,当添加第一个元素时,table容量调整为16
-
当元素个数大于阈值(16*0.75=12)时,会进行扩容,扩容后大小为原来的2倍。目的是减少调整元素的个数
-
jdk1.8 当链表长度大于8,并且集合元素个数大于等于64时,调整为红黑树,目的是提高执行效率
-
jdk1.8 当链表长度小于6时,调整成链表
-
jdk1.8 以前,链表是头插入,jdk1.8 以后是尾插入
/** * HashMap集合的使用 * 存储结构:哈希表(数组+链表+红黑树) * 使用key的hashcode和equals作为重复的依据 */ public class Map_HashMap { public static void main(String[] args) { //创建集合 HashMap<Map_Student, String> students = new HashMap<>(); //刚创建hsahmap之后没有添加元素 table=null size=0 目的:节省空间 //1. 添加元素 Map_Student student1 = new Map_Student("张三丰",25); Map_Student student2 = new Map_Student("令狐冲",22); Map_Student student3 = new Map_Student("任我行",31); students.put(student1, "武当"); students.put(student2, "华山"); students.put(student3, "魔教"); //键不可重复,值可重复 //想要以下的方式添加元素,添加不了,就需要重写hashcode和equals方法 students.put(new Map_Student("任我行",31), "魔教"); System.out.println("元素个数:"+students.size()); System.out.println(students); //2. 删除元素 // students.remove(student1); // System.out.println("删除之后:"+students.size()); // System.out.println(students); //3. 遍历元素 //3.1 使用keySet(); System.out.println("----------使用keySet();-------------"); for (Map_Student s : students.keySet()) { System.out.println(s+"---"+students.get(s)); } //3.2 使用entrySet(); System.out.println("----------使用entrySet();-------------"); for (Map.Entry<Map_Student, String> entry : students.entrySet()) { System.out.println(entry.getKey()+"---"+entry.getValue()); } //4. 判断 System.out.println(students.containsKey(student1)); System.out.println(students.containsKey(new Map_Student("令狐冲",22))); System.out.println(students.isEmpty()); System.out.println(students.containsValue("魔教")); } } //学生类 public class Map_Student { private String name; private int stuNo; public Map_Student(String name, int stuNo) { this.name = name; this.stuNo = stuNo; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getStuNo() { return stuNo; } public void setStuNo(int stuNo) { this.stuNo = stuNo; } @Override public String toString() { return "Map_Student{" + "name='" + name + '\'' + ", stuNo=" + stuNo + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Map_Student that = (Map_Student) o; return stuNo == that.stuNo && Objects.equals(name, that.name); } @Override public int hashCode() { return Objects.hash(name, stuNo); } }
Hashtable
◆ Hashtable(开发上基本不用了):
-
jdk1.0版本,线程安全,运行效率慢
-
不允许 null 作为 key 或是 value
Properties
◆ Hashtable 的子类,要求 key 和 value 都是String。通常用于配置文件的读取
TreeMap
◆ 实现了SortedMap接口(是Map的子接口),可以对key自动排序
/** * TreeMap的使用 * 存储结构:红黑树 */ public class Map_TreeMap { public static void main(String[] args) { //创建集合(如果不想实现Comparable接口,那就在创建集合的时候定制比较) // TreeMap<Map_Student, String> treeMap = new TreeMap<>(new Comparator<Map_Student>() { // @Override // public int compare(Map_Student o1, Map_Student o2) { // //这里写比较规则 // return 0; // } // }); TreeMap<Map_Student, String> treeMap = new TreeMap(); //1. 添加元素,要求元素实现Comparable接口 Map_Student s1 = new Map_Student("张三丰",25); Map_Student s2 = new Map_Student("令狐冲",22); Map_Student s3 = new Map_Student("任我行",31); treeMap.put(s1, "武当"); treeMap.put(s2, "华山"); treeMap.put(s3, "魔教"); treeMap.put(new Map_Student("林平之",31), "峨眉"); System.out.println("元素个数:"+treeMap.size()); System.out.println(treeMap); //2. 删除 //treeMap.remove(s1); // treeMap.remove(new Map_Student("令狐冲", 22)); // System.out.println("删除之后:"+treeMap.size()); // System.out.println(treeMap); //3. 遍历 //3.1 keySet(); System.out.println("----------keySet();------------"); for (Map_Student s : treeMap.keySet()) { System.out.println(s+"------"+treeMap.get(s)); } //3.2 entrySet(); System.out.println("----------keySet();------------"); for (Map.Entry<Map_Student, String> entry : treeMap.entrySet()) { System.out.println(entry.getKey()+"------"+entry.getValue()); } //4. 判断 System.out.println(treeMap.containsKey(s1)); System.out.println(treeMap.containsKey(new Map_Student("令狐冲",22))); } }
Colletions工具类
◆ 概念:集合工具类,定义了除了存取以外的集合常用方法
◆ 方法:
-
public static void reverse(List<?> list) //反转集合中元素的顺序
-
public static void shuffle(List<?> list) //随机重置集合元素的顺序
-
public static void sort(List<T> list) //升序排序(元素类型必须实现Comparable接口)
/** * Collection工具类的使用 * */ public class Collections01 { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(20); list.add(2); list.add(10); list.add(26); list.add(14); //sort排序 System.out.println("排序之前:"+list.toString()); Collections.sort(list); System.out.println("排序之后:"+list.toString()); //二分查找 binarySearch int i = Collections.binarySearch(list, 10); System.out.println(i); //复制 copy List<Object> list2 = new ArrayList<>(); for (int j = 0; j < list.size(); j++) { list2.add(0); } Collections.copy(list2,list); System.out.println(list2.toString()); //反转 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[0]); System.out.println(arr.length); System.out.println(Arrays.toString(arr)); //数组转成集合 System.out.println("--------数组转成集合---------"); String[] names = {"张三","李四","王五"}; //通过这个方法转成的集合,是一个受限集合,不能添加和删除 List<String> list3 = Arrays.asList(names); //list3.add("赵六"); //list3.remove(1); System.out.println(list3); //把基本类型数组转成集合时,需要修改为包装类 Integer[] nums = {100,200,300,150,500}; List<Integer> list4 = Arrays.asList(nums); System.out.println(list4.toString()); } }
总结
◆ 集合的概念:
对象的容器,和数组类似,定义了对多个对象进行操作的常用方法
◆ LIst集合:
有序、有下标、元素可以重复。(ArrayList(存储结构:数组)、LinkedList(双向链表)、Vector(不常用))
◆ Set集合:
无序、无下标,元素不可重复。(HashSet(哈希表:数组+链表)、TreeSet(数组+链表+红黑树))
◆ Map集合:
存储一对数据,无序、无下标,键不可重复,值可重复。(HashMap(哈希表)、HashTable(不常用)、TreeMap(红黑树))
◆ Collections:
集合工具类,定义了除了存取以外的集合常用方法。