概述
1.集合:对象的容器,定义了对多个对象进行操作的常用方法。可以实现数组的功能。
2.和数组的区别:
1>数据长度固定,集合长度不固定
2>数组可以存储基本类型和引用类型,集合只能存储引用类型
Collection体系集合
Collection父接口
是所有单列集合的顶级接口,任何单列集合都是他的子接口,或者是实现类, 该接口中定义的方法,是所有单列集合的共性方法.
特点:代表一组任意类型的对象,无需、无下标、不能重复。
方法:
学生类(Student)代码:
package Collections; import java.util.Objects; //学生类 public class Student { private String name; private int age; 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 "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; return age == student.age && Objects.equals(name, student.name); } }
不含构造方法的代码测试:
package Collections; 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(); // 1.添加元素 collection.add("苹果"); collection.add("西瓜"); collection.add("榴莲"); System.out.println("元素个数"+collection.size()); System.out.println(collection); // 2.删除元素 collection.remove("榴莲"); System.out.println(collection); // collection.clear();//清空元素 // 3.遍历元素 // 3.1 使用增强for for (Object o : collection) { System.out.println(o); } // 3.2使用迭代器,专门用来遍历集合的一种方式 // hasNext();有没有下一个元素 // next();获取下一个元素 // remove()删除当前元素 Iterator it=collection.iterator(); while (it.hasNext()){ // 在迭代过程中不能使用collection其他方法 String obj = (String)it.next(); System.out.println(obj); //it.remove();//迭代器提供的方法 } System.out.println(collection.size()); // 4.判断 System.out.println(collection.contains("西瓜")); System.out.println(collection.isEmpty()); } }
含构造方法的代码测试:
package Collections; 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("uzi", 22); Student s2 = new Student("ming", 23); Student s3 = new Student("doinb", 25); // 1.添加数据 collection.add(s1); collection.add(s2); collection.add(s3); System.out.println("元素个数" + collection.size()); System.out.println(collection.toString()); // 2.删除 collection.remove(s3); System.out.println("删除之后" + collection.size()); // collection.clear();//删除集合中的内存地址,并不能删除已经创建的对象 // 3.遍历 // 第一种 for (Object o : collection) { Student s=(Student) o;//强制类型转换 System.out.println(s.toString()); } // 第二种 Iterator it=collection.iterator(); while (it.hasNext()){ Student s=(Student)it.next();//强制类型转换 System.out.println(s.toString()); } // 4.判断 System.out.println(collection.contains(s1)); System.out.println(collection.isEmpty()); } }
List子接口
特点:有序、有下标、元素可以重复
方法:
代码测试:
package Collections; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.ListIterator; //List子接口的使用 //特点1.有序有下标 2.可以重复 public class Demo03 { public static void main(String[] args) { // 创建集合对象 List list=new ArrayList(); // 1.添加元素 list.add("苹果"); list.add("小米"); list.add("华为"); System.out.println("元素个数"+list.size()); System.out.println(list.toString()); // 2.删除元素 list.remove("苹果");//相当于list.remove(0); System.out.println("元素个数"+list.size()); System.out.println(list.toString()); // list.clear();//清空 // 3.遍历 // 第一种for for (int i = 0; i < list.size(); i++) { System.out.println(list.get(i)); } // 第二种增强for for (Object o : list) { System.out.println(o); } // 第三种使用迭代器 Iterator it=list.iterator(); while (it.hasNext()){ System.out.println(it.next()); } // 第四种列表迭代器,和Iterator区别,ListIterator可以向前向后遍历,也可以添加删除修稿元素 ListIterator lit=list.listIterator(); while (lit.hasNext()){ System.out.println(lit.nextIndex()+":"+lit.next()); } System.out.println("=========================="); while (lit.hasPrevious()){ System.out.println(lit.previousIndex()+":"+lit.previous()); } // 4.判断 System.out.println(list.contains("苹果")); System.out.println(list.isEmpty()); // 5.获取位置 System.out.println(list.indexOf("华为")); } }
List数字数据测试:
package Collections; import java.util.ArrayList; import java.util.List; public class Demo04 { public static void main(String[] args) { List list=new ArrayList(); // 添加数字数据,(自动装箱) list.add(10); list.add(20); list.add(30); list.add(40); list.add(50); System.out.println("元素个数"+list.size()); System.out.println(list.toString()); // 2.删除操作 list.remove(0); // list.remove(new Integer(20));//和上边相同,相当于拆箱 // 3.补充方法subList,返回子集合,含头不含尾 List subList=list.subList(1,3); System.out.println(subList.toString()); } }
ArrayList【重点】
数组结构实现,查询快,增删慢
默认容量:DEFAULT_CAPACITY=10,如果没有向集合中添加任何元素时,容量为0,添加任意一个容量变为10,再添加元素时会每次扩容5个元素
代码测试:
package Collections; import java.util.ArrayList; import java.util.Iterator; import java.util.ListIterator; //ArrayList 的使用 //数组结构实现,查询快,增删慢 public class Demo05 { public static void main(String[] args) { // 创建集合:size 0 容量 0 ArrayList arrayList=new ArrayList(); // 1.添加元素 Student s1 = new Student("uzi", 22); Student s2 = new Student("ming", 25); Student s3 = new Student("rookie", 26); Student s4 = new Student("xiaohu", 22); arrayList.add(s1); arrayList.add(s2); arrayList.add(s3); arrayList.add(s4); System.out.println("元素个数"+arrayList.size()); System.out.println(arrayList.toString()); // 2.删除元素 // arrayList.remove(s1); // arrayList.remove(0); arrayList.remove(new Student("uzi", 22));//重写equals方法,和上边两个效果相同 System.out.println(arrayList.toString()); // 3.遍历元素 // 1.迭代器 Iterator it=arrayList.iterator(); while (it.hasNext()){ Student s=(Student) it.next(); System.out.println(s); } System.out.println("=========================="); // 2.列表迭代器 ListIterator lit=arrayList.listIterator(); while (lit.hasNext()){ Student s=(Student) lit.next(); System.out.println(s.toString()); } // 4.判断 System.out.println(arrayList.contains(new Student("xiaohu",22))); } }
Vector
数组结构实现,查询快,增删慢,线程安全
迭代的关键字变成了枚,遍历使用枚举器
测试代码:
package Collections; import java.util.Enumeration; import java.util.Vector; //vector集合的使用 //村树结构,数组 public class Demo06 { public static void main(String[] args) { // 创建集合 Vector vector=new Vector(); // 1.添加元素 vector.add("草莓"); vector.add("苹果"); vector.add("桃子"); vector.add("葡萄"); System.out.println("元素个数"+vector.size()); // 2.删除 vector.remove(0); // vector.clear(); // 3.遍历,使用枚举器 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.其他方法 vector.firstElement();//第一个元素 vector.lastElement();//最后一个元素 vector.elementAt(0);//索引 } }
LinkedList
链表结构实现,增删快,查询慢
测试代码:
package Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.ListIterator; //LinkedList的使用 //存储结构,双向链表 public class Demo07 { public static void main(String[] args) { // 1.创建集合 LinkedList linkedList=new LinkedList(); // 2.添加元素 Student s1 = new Student("uzi", 22); Student s2 = new Student("ming", 25); Student s3 = new Student("rookie", 26); Student s4 = new Student("xiaohu", 22); linkedList.add(s1); linkedList.add(s2); linkedList.add(s3); linkedList.add(s4); System.out.println("元素个数"+linkedList.size()); System.out.println(linkedList.toString()); // 3.删除元素 linkedList.remove(s2); System.out.println(linkedList.toString()); // linkedList.clear(); // 4.遍历 // 4.1for for (int i = 0; i < linkedList.size(); i++) { System.out.println(linkedList.get(i)); } System.out.println("====================="); // 4.2加强for for (Object o : linkedList) { Student s=(Student)o; System.out.println(s); } System.out.println("====================="); // 4.3迭代器 Iterator it=linkedList.listIterator(); while (it.hasNext()){ Student s=(Student) it.next(); System.out.println(s.toString()); } // 4.4功能强大的迭代器,列表迭代器 ListIterator lit = linkedList.listIterator(); while (lit.hasNext()){ Student s=(Student) lit.next(); System.out.println(s.toString()); } // 5.判断 System.out.println(linkedList.isEmpty()); System.out.println(linkedList.contains(s2)); // 6.获取 System.out.println(linkedList.indexOf(s4)); } }
集合Set子接口
特点:无序、无下标、元素不可重复。
方法:全部继承自Collection的方法。
package Collections import java.util.HashSet; import java.util.Iterator; import java.util.Set /** * 测试Set接口的使用 * 特点:无序、没有下标、不能重复 */ public class Demo08 { public static void main(String[] args) { // 创建集合 Set<String> set = new HashSet<>(); // 1.添加数据 set.add("小米"); set.add("苹果"); set.add("华为"); System.out.println("集合个数" + set.size()); System.out.println(set.toString()); // 2.删除数据 set.remove("小米"); System.out.println(set.toString()); // set.clear(); // 3.遍历 // 3.1增强for,由于没有下标,是无序的所以没法用for for (String s : set) { System.out.println(s); } // 3.2使用迭代器 Iterator<String> it = set.iterator(); while (it.hasNext()) { System.out.println(it.next()); } // 4.判断 System.out.println(set.contains("华为")); System.out.println(set.isEmpty()); } }
ps:这里使用到了泛型集合,并附上泛型的讲解文章:泛型集合
HashSet【重点】
存储结构:哈希表(数组+链表+红黑树)
存储过程:
1.根据hashcode计算v保存的位置,如果此位置为空,则直接保存数据,如果不为空,则执行第二步
2.再执行equals方法,如果equals为true,则认为是true,否则形成链表
代码测试
package Collections; import java.util.HashSet; import java.util.Iterator; //HashSet集合的使用 //存储结构:哈希表(数组+链表+红黑树) //存储过程: //1.根据hashcode计算v保存的位置,如果此位置为空,则直接保存数据,如果不为空,则执行第二步 //2.再执行equals方法,如果equals为true,则认为是true,否则形成链表。 public class Demo09 { public static void main(String[] args) { // 新建集合 HashSet<String> hashSet=new HashSet<String>(); // 1.添加元素 hashSet.add("苹果"); hashSet.add("橘子"); hashSet.add("桃子"); hashSet.add("桃子");//元素没有添加进去,不允许重复 hashSet.add("香蕉");//无序的 System.out.println(hashSet.toString()); // 2.删除 hashSet.remove("桃子"); System.out.println(hashSet.toString()); // 3.遍历 // 1.增强for for (String s : hashSet) { System.out.println(s); } System.out.println("==================="); // 2.使用迭代器 Iterator it=hashSet.iterator(); while (it.hasNext()){ System.out.println(it.next()); } // 4.判断 System.out.println( hashSet.contains("葡萄")); System.out.println(hashSet.isEmpty()); HashSet<Student> hashSet2=new HashSet();//后边也可以省略<Student> Student s1= new Student("uzi",22); Student s2 = new Student("ming",25); Student s3 = new Student("ming",25);//添加不同的对象可以重复 hashSet2.add(s1); hashSet2.add(s2); hashSet2.add(s3); hashSet2.add(s3);//无序,不可以重复添加 hashSet2.add(new Student("uzi",22)); System.out.println(hashSet2.toString());//重写hashcode和equals方法 // hashSet2.remove(s1); hashSet2.remove(new Student("uzi",22));//可以删掉 System.out.println(hashSet2); System.out.println("============="); hashSet2.add(s1); for (Student student : hashSet2) { System.out.println(student); } System.out.println("============="); Iterator<Student> ite= hashSet2.iterator(); while (ite.hasNext()){ System.out.println(ite.next()); } System.out.println(hashSet2.contains(s1)); System.out.println(hashSet2.contains(new Student("uzi",22)));//和上边相同 } }
PS:一般需要在对象类中重写hashCode方法:
//基于HashCode实现元素不重复 //当存入元素的哈希码相同时,会调用equals进行确认,如过结果为true,则拒绝后者存入。 public int hashCode() { return Objects.hash(name, age); }
TreeSet
基于排列顺序实现元素不重复,不需要重写hashCode方法
实现了SortedSet接口,对集合元素自动排序
如果类型时对象必须实现对象类的Comparable接口,指定排序规则,实现方法:
public int compareTo(Student o) { int n1=this.getName().compareTo(o.getName()); int n2=this.getAge()-o.getAge(); return n1==0?n2:n1; }
或者通过CompareTo方法确定是否为重复元素,需要在创建集合的时候,指定比较规则,实现方法:
//需要在创建集合的时候,指定比较规则,例子: //Comparator:实现定制比较(比较器),不需要实现Comparable接口 TreeSet<Student> ts=new TreeSet<>(new Comparator<Student>() { public int compare(Student o1, Student o2) { int n1=o1.getAge()-o2.getAge(); int n2=o2.getName().compareTo(o2.getName()); return n1==0?n2:n1; } });
TreeSet测试代码:(采用的是使用Comparator定制比较)
package Collections; import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet; public class Demo11 { public static void main(String[] args) { //Comparator:实现定制比较(比较器),不需要实现Comparable接口 // 创建集合,并指定比较规则 TreeSet<Student> ts=new TreeSet<>(new Comparator<Student>() { public int compare(Student o1, Student o2) { int n1=o1.getAge()-o2.getAge(); int n2=o2.getName().compareTo(o2.getName()); return n1==0?n2:n1; } }); Student s1 = new Student("uzi", 22); Student s2 = new Student("ming", 25); Student s3 = new Student("rookie", 26); Student s4 = new Student("ming", 25); ts.add(s1); ts.add(s2); ts.add(s3); ts.add(s3); System.out.println(ts.toString()); ts.remove(s1); // treeSet1.remove(new Student("uzi", 22));//和和上边效果相同 for (Student student : ts) { System.out.println(student); } Iterator<Student> iterator1 = ts.iterator(); while (iterator1.hasNext()){ System.out.println(iterator1.next());; } System.out.println(ts.contains("s2")); System.out.println(ts.isEmpty()); } }
Map体系集合
Map父接口
Map接口的使用
特点(1.)存储键值对(2)键不能重复,值可以重复(3)无序
HashMap线程不安全,运行效率快,允许null作为key或是value
Hashtable线程安全,运行效率慢,不允许null作为key或是value
Properties的子类,要求key和value都是String 。通常用于配置文件的读取
演示代码:
package Collections.Map; import java.util.HashMap; import java.util.Map; //Map接口的使用 //特点(1.)存储键值对,(2)键不能重复,值可以重复(3)无序 public class Demo01 { public static void main(String[] args) { // 1.创建Map集合 Map<String, String> map = new HashMap<>(); // 1.添加元素 map.put("cn", "中国"); map.put("cn", "zhongguo ");//键重复无法添加,而且由于键相同,所以值被修改 map.put("china", "中国 ");//值重复,键不重复,可以添加 map.put("uk", "英国"); map.put("usa", "美国"); System.out.println(map.size()); System.out.println(map.toString()); // 2.删除元素 map.remove("china");//输入要删除的键即可 map.clear(); System.out.println(map.toString()); // 3.遍历***重点 // 3.1使用keySet // Set<String> keyset = map.keySet(); // for (String s : keyset) { // System.out.println(s+"----"+map.get(s)); // } for (String s : map.keySet()) {//和上边效果一样 System.out.println(s + "----" + map.get(s)); } // 3.2使用entrySet方法 // Set<Map.Entry<String, String>> entries = map.entrySet(); // for (Map.Entry<String, String> entry : entries) { // System.out.println(entry.getKey() + "----" + entry.getValue()); // } for (Map.Entry<String, String> entry : map.entrySet()) { System.out.println(entry.getKey() + "----" + entry.getValue()); }//和上边效果相同 // entrySet方法和keySet相比,效率更高,所以建议使用entrySet遍历 // 4.判断 System.out.println(map.containsKey("usa")); System.out.println(map.containsValue("中国")); System.out.println(map.isEmpty()); } }
HashMap集合的使用
存储结构:哈希表(数组+链表+红黑
使用key的hashCode和equals作为判断是否重复依据,所以要在Student类中重写equals和hashcode方法创建对象类。
创建对象类:Student类:
package Collections.Map import java.util.Objects; public class Student implements Comparable<Student> { private String name; private int age; private int stuNo; public Student(String name, int age, int stuNo) { this.name = name; this.age = age; this.stuNo = stuNo; } 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; } public int getStuNo() { return stuNo; } public void setStuNo(int stuNo) { this.stuNo = stuNo; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + ", stuNo=" + stuNo + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o; return age == student.age && stuNo == student.stuNo && Objects.equals(name, student.name); } @Override public int hashCode() { return Objects.hash(name, age, stuNo); } @Override public int compareTo(Student o) { int n1=this.name.compareTo(o.name); int n2=this.age-o.age; return n1==0?n2:n1; } }
HashMap集合测试:
package Collections.Map; import java.util.HashMap; import java.util.Map; //HashMap集合的使用 //存储结构:哈希表(数组+链表+红黑树) //使用key的hashCode和equals作为判断是否重复依据,所以要在Student类中重写equals和hashcode方法 public class Demo02 { public static void main(String[] args) { // 创建集合 HashMap<Student, String> stu = new HashMap<Student, String>(); // 1.添加元素 Student s1 = new Student("小高", 23, 20211366); Student s2 = new Student("小杨", 24, 20211368); Student s3 = new Student("小凌", 22, 20211336); stu.put(s1, "吉林"); stu.put(s2, "河南"); stu.put(s3, "河南"); stu.put(s3, "安徽");//key相同,value被覆盖,无序 stu.put(new Student("小高", 23, 20211366), "河南");//重复添加,需要去重 System.out.println(stu.toString()); // 2.删除 // stu.remove(s1); stu.remove(new Student("小高", 23, 20211366));//和上边效果相同 // stu.clear(); System.out.println(stu.toString()); // 3.遍历 // 3.1使用keySet(); for (Student key : stu.keySet()) { System.out.println(key+"---"+stu.get(key)); } // 3.2使用entrySet for(Map.Entry<Student, String> s:stu.entrySet()){ System.out.println(s.getKey()+"---"+s.getValue()); } // 4判断 System.out.println(stu.containsKey(new Student("小杨", 23, 20211366))); System.out.println(stu.containsValue("河南")); } }
TreeMap的使用
存储结构:红黑树
一般来说在使用TreeMap的时候需要使用Comparator:实现定制比较(比较器),不需要实现Comparable接口,或者在对象类中继承Comparable接口,并重写compareTo方法。(在上边的Student类中已写)
为什么要进行上一步操作?
这跟hashMap重写equals和hashCode方法效果相同,为了在让添加元素的时候不会让元素重复
测试代码:
package Collections.Map; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; //Collections工具类 public class Demo04 { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(23); list.add(24); list.add(29); list.add(26); list.add(23); // sort排序 System.out.println("排序之前" + list.toString()); Collections.sort(list); System.out.println("排序之后" + list.toString()); // binarySearch二分查找 Collections.binarySearch(list, 24); // copy复制 List<Integer> list2 = new ArrayList<>(); for (int i = 0; i < list.size(); i++) { list2.add(0); } Collections.copy(list2, list);//要要求集合的元素个数相同,相当于给list2赋值 System.out.println(list2.toString()); // reverse反转 Collections.reverse(list); System.out.println(list.toString()); // shuffle将集合元素打乱 Collections.shuffle(list); System.out.println(list); // 补充 // list转换成数组 Integer[] arr= list.toArray(new Integer[0]); System.out.println(arr.length); System.out.println(Arrays.toString(arr)); // 数组转换成集合 String[] names={"张三","李四","王五"}; Integer[] nums={1,2,4,8,9,7,12}; // 集合是一个受限集合,不能添加和删除,把基本数据类型转换为集合时,需要修改为包装类 List<String> list3=Arrays.asList(names); List<Integer> list4=Arrays.asList(nums); // list3.add("高柳"); System.out.println(list3); System.out.println(list4); } }
总结:
PS:
迭代器分为Iterator和ListIterator两种,一般来说ListIterator提供的方法更多,更好用。
枚举提供了遍历Vector和HashTable类型集合元素的功能。
对于List,一般会用到Collections工具类
Collections工具类提供以下方法对List进行排序操作
void reverse(List list):反转
void shuffle(List list),随机排序
void sort(List list),按自然排序的升序排序
void sort(List list, Comparator c);定制排序,由Comparator控制排序逻辑
void swap(List list, int i , int j),交换两个索引位置的元素
void rotate(List list, int distance),旋转。当distance为正数时,将list后distance个元素整体移到前面。当distance为负数时,将 list的前distance个元素整体移到后面。
测试代码:
package Collections.Map; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.List; //Collections工具类 public class Demo04 { public static void main(String[] args) { List<Integer> list = new ArrayList<>(); list.add(23); list.add(24); list.add(29); list.add(26); list.add(23); // sort排序 System.out.println("排序之前" + list.toString()); Collections.sort(list); System.out.println("排序之后" + list.toString()); // binarySearch二分查找 Collections.binarySearch(list, 24); // copy复制 List<Integer> list2 = new ArrayList<>(); for (int i = 0; i < list.size(); i++) { list2.add(0); } Collections.copy(list2, list);//要要求集合的元素个数相同,相当于给list2赋值 System.out.println(list2.toString()); // reverse反转 Collections.reverse(list); System.out.println(list.toString()); // shuffle将集合元素打乱 Collections.shuffle(list); System.out.println(list); // 补充 // list转换成数组 Integer[] arr= list.toArray(new Integer[0]); System.out.println(arr.length); System.out.println(Arrays.toString(arr)); // 数组转换成集合 String[] names={"张三","李四","王五"}; Integer[] nums={1,2,4,8,9,7,12}; // 集合是一个受限集合,不能添加和删除,把基本数据类型转换为集合时,需要修改为包装类 List<String> list3=Arrays.asList(names); List<Integer> list4=Arrays.asList(nums); // list3.add("高柳"); System.out.println(list3); System.out.println(list4); } }