Java集合框架主要讲解
- 集合的概念
- Collection体系集合
- List接口与实现类
- Set接口与实现类
- Map接口与实现类
- 泛型集合与工具类
集合的概念
一.概念:对象的容器,定义了多个对象进行操作的常用方法。可以实现数组的功能。
二.和数组的区别
- 数组长度固定,集合长度不固定
- 数组可以储存基本类型和引用类型,集合只能存储引用类型(可以通过装箱存储基本类型)
三.位置:java.util.*;
Collection体系集合
有序(存储与遍历的顺序一致)无序(存储与遍历的顺序不同)
Collection,List,Set 是接口不能new 所以要new他们的实现类
Collection接口
Collection使用(1)
存储字符串
// 创建集合( 使用ArrayList() )
Collection collection = new ArrayList();
// 1.添加元素使用add()方法
collection.add("lihao");
collection.add("liyate");
collection.add("huxin");
// 使用size()方法打印集合元素的个数
System.out.println("元素个数为:"+collection.size()); // 元素个数为:3
System.out.println(collection);// [liho, liyte, hxin]
// 2.删除元素:remove()方法
collection.remove("liyte");
System.out.println("元素个数为:"+collection.size()); // 元素个数为:2
// 3.clear()清空操作
collection.clear();
System.out.println(collection.size()); // 0
// 4.遍历集合元素(重点)
//(1).使用增强for (不能使用for,因为使用for需要使用下标,collection方法中没有设计下标的)
for (Object o : collection) {
System.out.println(o);
}
//(2).使用iterator迭代器(迭代器是专门遍历集合的一种方式)
// iterator中的三个方法:
// hasNext();判断有没有下一个元素
// next();获取下一个元素
// remove();删除当前元素(是迭代器中的remove方法不是collection中的)
Iterator it = collection.iterator();
// 使用循环来遍历
while(it.hasNext()){
Object next = it.next();
System.out.println(next);
it.remove(); // 此处不能使用collection.remove()
}
System.out.println(collection.size()); // 0
// 注意事项:在使用迭代器时不能使用collection的方法来改变集合的元素
// 5.判断
// (1).contains()判断是否包含某个元素
System.out.println(collection.contains("xigua")); // false
// (2).isEmpty()判断该集合是否为空
System.out.println(collection.isEmpty()); // true
Collection使用(2)
存储学生信息
package practice;
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 +
'}';
}
}
package practice;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class test {
public static void main(String[] args) {
// 创建一个Collection对象
Collection collection = new ArrayList();
Student student = new Student("zhangsan",33);
Student student1 = new Student("lisi",23);
Student student2 = new Student("wangwu",13);
// 1.添加数据
collection.add(student);
collection.add(student1);
collection.add(student2);
System.out.println(collection.size()); // 3
// 需要在Student类中重写toString()方法 看起来更加舒服
System.out.println(collection.toString()); // [Student{name='zhangsan', age=33}, Student{name='lisi', age=23}, Student{name='wangwu', age=13}]
// 2.删除
collection.remove(student);
System.out.println(collection.size()); // 2
collection.remove(new Student("lisi",23));
System.out.println(collection.size()); // 还是2 因为你又新建了一个,与原先的没有关系
// 3.1遍历--增强for
for (Object o : collection) {
Student s= (Student) o; // 强转为Student类型
System.out.println(s);
}
System.out.println("----------------");
// 3.2遍历--迭代器 iterator
Iterator it = collection.iterator();
while(it.hasNext()){
Object next = it.next();
System.out.println(next);
}
/*
Student{name='lisi', age=23}
Student{name='wangwu', age=13}
*/
// 判断
System.out.println(collection.contains(student)); //false
System.out.println(collection.isEmpty()); //false
}
}
List接口使用(1)
List继承了Collection,所以List包含Collection中的所有方法
package practice;
import java.util.*;
public class Test {
public static void main(String[] args) {
// 先创建一个集合对象
List list = new ArrayList();
// 1. 添加元素
list.add("huawei");
list.add("xiaomi");
list.add("apple");
System.out.println(list.size());
System.out.println(list); // [huawei, xiaomi, apple]
// // 2.删除
// list.remove("xiaomi");
// System.out.println(list); //[huawei, apple]
// // 因为list集合有下标所以可以删除指定位置的元素
// list.remove(0);
// System.out.println(list); // [apple]
//3.1遍历--使用for
//使用get()方法来返回集合中指定位置的元素
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
//3.2遍历--使用增强for
for (Object o : list) {
System.out.println(o);
}
//3.3遍历--使用迭代器
//3.4遍历--使用列表迭代器
//ListIterator可以向前或者向后遍历,可以实现 添加元素,删除元素,修改元素
ListIterator lit = list.listIterator();
// 从前向后
while(lit.hasNext()){
System.out.println(lit.nextIndex()+":"+lit.next());
}
//从后向前
while(lit.hasPrevious()) {
lit.set("lihao");
System.out.println(lit.previousIndex() + ":" + lit.previous());
}
//4.两个判断--contains(),isEmpty()
//5.获取位置--使用indexOf()方法来获取集合元素所在的位置
System.out.println(list.indexOf("huawei"));
}
}
List接口的使用(2)
//1.添加 数字数据 (隐含装箱操作)
list.add(20);
list.add(30);
list.add(40);
list.add(50);
list.add(60);
System.out.println(list.size());
System.out.println(list);
//2.删除操作--注意:需要将20转为Object或者Integer的才能删除 在不误认为索引
list.remove((Object) 20);
System.out.println(list);
//3.sublist():返回一个子集合
List list1 = list.subList(1, 4);
System.out.println(list1); // [40, 50, 60]
List实现类
ArrayList使用
ArrayList arrayList = new ArrayList();
//1.添加元素--可以添加类对象
Student s1 = new Student("fjlsa",22);
Student s2 = new Student("jfdsal",23);
Student s3 = new Student("jal",34);
arrayList.add(s1);
arrayList.add(s2);
arrayList.add(s3);
System.out.println(arrayList); // [Student{name='fjlsa', age=22}, Student{name='jfdsal', age=23}, Student{name='jal', age=34}]
//2.删除元素
arrayList.remove(new Student("fjlsa",22)); // 删不掉因为ArrayList中使用equal的方法比较地址,他是新创建的,所以需要重写equal方法
System.out.println(arrayList); // [Student{name='jfdsal', age=23}, Student{name='jal', age=34}]
System.out.println(arrayList.size()); // 2
//3.遍历--迭代器
Iterator it = arrayList.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
// 列表迭代器 ListIterator
ListIterator lit = arrayList.listIterator();
while (lit.hasPrevious()){
System.out.println(lit.previous());
}
//4.判断
System.out.println(arrayList.contains(new Student("jal",34))); // true 因为重写equals方法了
//5.查找
System.out.pritln(arrayList.indexOf(s3)); // 1 如果查找内容不存在就返回-1
Vector使用
// 先创建一个集合
Vector vector = new Vector();
//1.添加
vector.add("苹果");
vector.add("香蕉");
vector.add("橘子");
System.out.println(vector.size());
System.out.println(vector);
//2.1删除 remove(可以是下标 也可以是具体值)
//2.2清空 clear()
//3.遍历---Vector 枚举器 elements()
Enumeration elements = vector.elements();
while(elements.hasMoreElements()){
System.out.println(elements.nextElement());
}
//4.判断
//5.vector其他方法:firstElement()得到第一个元素 listElement()得到最后一个元素 get(下标)获得某个位置的元素
Object o = vector.lastElement();
System.out.println(o);
System.out.println(vector.get(2));
LinkedList使用
// 创建集合
LinkedList linkedList = new LinkedList();
// 1.添加
Student s1 = new Student("afsa",22);
Student s2 = new Student("afdas",33);
Student s3 = new Student("afrrr",34);
linkedList.add(s1);
linkedList.add(s2);
linkedList.add(s3);
linkedList.add(s3);
System.out.println(linkedList.size());
System.out.println(linkedList.toString());
//2.删除 remove() 清空 clear()
//3.1遍历--for 需要使用get方法获取该位置
for (int i = 0; i < linkedList.size(); i++) {
System.out.println(linkedList.get(i));
}
//3.2--增强for
for (Object o : linkedList) {
System.out.println(o);
}
//3.3--迭代器,列表迭代器
//4.判断--contains(),isEmpty()
//5.获取位置--indexOf
LinkedList的源码分析
ArrayList与LinkedList的区别
ArrayList是数组
LinkedList是双向链表
泛型概述
泛型类
public class Test<T> {
// 语法:在类名后面<T> 类型占位符可以为多个用逗号隔开
// 类型占位符(表示一种 引用 类型,不能是基本类型)
//使用泛型T
//1.创建变量
T t;
//2.泛型作为方法的参数
public void app(T t){
System.out.println(t);
}
//3.泛型作为方法的返回值
public T getT (){
return t;
}
//注意: 1.泛型T不能new 因为不知道它是什么类型(不知构造方法能不能调佣)
// 2.不同的泛型对象之间不能相互赋值
}
public class 实现 {
public static void main(String[] args) {
// 用泛型类创建了一个对象
// 在使用时需要传入实际的引用对象
Test<String> test = new Test<>();
// 只能向里面传字符串
test.t= "afas";
test.app("大家好");
String q = test.getT();
System.out.println(q);
}
}
泛型接口
第一种在创建接口实现类时传入实际类型
- 接口
public interface test<T> {
// 泛型接口语法:接口名<T>
// 注意:泛型接口中不能泛型静态常量
String name = "张三";
T show(T t);
}
- 实现类
public class shixian implements test<String> {
@Override
public String show(String s) {
System.out.println("实验室真是死亡");
return s;
}
}
- 测试
public class Outer {
public static void main(String[] args) {
shixian shixian = new shixian();
String a = shixian .show("干就完了");
System.out.println(a);
}
}
第二种在创建接口实现类仍然为泛型类
- 接口
public interface test<T> {
// 泛型接口语法:接口名<T>
// 注意:不能泛型静态常量
String name = "张三";
T show(T t);
}
- 实现类
public class shixian <T> implements test<T> {
@Override
public T show(T t) {
return t;
}
}
- 测试
public class Outer {
public static void main(String[] args) {
shixian <Integer> shi = new shixian<>();
Integer show = shi.show(1000);
System.out.println(show);
}
}
泛型方法
泛型方法语法: 返回值类型
public class shixian {
// 泛型方法语法:<T> 返回值类型
public <T> T show(T t){
System.out.println(t);
return t;
}
}
public class Outer {
public static void main(String[] args) {
shixian sx = new shixian();
// 调用泛型方法 :直接传参数就行,与正常调用一样
sx.show("zhongguo");
sx.show(200);
}
}
泛型的好处
重用性高:可以传入任何类型的参数
泛型集合
// 使用泛型来定义指定类型的集合(防止类型转换造成的错误)--字符串
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("app");
arrayList.add("appa");
arrayList.add("appb");
//arrayList.add(30); 不能添加int类型的了
//在遍历的时候为String了
//如果要添加学生类对象则 ArrayList<String> arrayList = new ArrayList<>();
ArrayList<Student> arrayList1 = new ArrayList<>();
Student s1 = new Student("hfdsa", 34);
arrayList1.add(s1);
System.out.println(arrayList1);
// 迭代器也是泛型的
Iterator<Student> it = arrayList1.iterator();
while (it.hasNext()){
// it.next() 为Student类型的了不是Object了
Student next = it.next();
System.out.println(it.next());
Set集合的概述
Set接口的使用
- 与上面方法全部一致
HashSet的存储方式
-
注意下面第四条语句可以实现,但是Set不重复 怎么实现不重复存入呢?
-
那就要在Student中重写HashCode方法了实现以上功能
-
但是这样以后也加进来了,形成一个链表,因为重写了hashcode所以他们的hashCode相同
(位置是同一个),为啥加进来了呢?–这是因为equals为false了,这个时候需要在Student类中重写equals方法
-
这样第四条语句就无法实现了 , 存不进来了
-
因为你上面重写了hashCode与equals方法所以这样可以删掉
-
为true,因为重写了两个方法
-
快捷方法: alt+ins , 选择方法
TreeSet
- 存储结构:红黑树
- 如果你想向TreeSet中添加Student类对象
- 首先必须实现Comparable接口,接口是泛型的可以为Person
- 因为存储结构式二叉排序树,所以需要在CompareTo中重写比较规则
- comparable方法的返回值为零, 认为是重复
Comparator接口(比较器)
可以实现定制比较
在向TreeSet中存储Studet类对象时,就不是实现comparable接口了;
而是在创建集合的时候就写好了比较规则
// 创建一个集合,并指定比较规则
// 使用了匿名内部类
TreeSet<Student> treeSet = new TreeSet(new Comparator<Student>(){
@Override
// 比较规则
public int compare(Student o1, Student o2) {
int n1 = o1.getAge()-o2.getAge();
int n2 = o1.getName().compareTo(o2.getName());
return n1==0?n2:n1;
}
});
Student s1 = new Student("afdsa", 11);
Student s2 = new Student("sa", 12);
Student s3 = new Student("ew", 13);
treeSet.add(s1);
treeSet.add(s2);
treeSet.add(s3);
System.out.println(treeSet);
TreeSet的案例
要求:使用TreeSet集合实现字符串按照长度进行排序
//要求:使用TreeSet集合实现字符串按照长度进行排序
//需要使用comparator接口进行定制比较
TreeSet<String> treeSet = 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;
}
});
treeSet.add("aaa");
treeSet.add("baa");
treeSet.add("afds");
treeSet.add("a");
treeSet.add("dasfdsafdsa");
treeSet.add("w");
System.out.println(treeSet); // [a, w, aaa, baa, afds, dasfdsafdsa]
Map集合概述
Map父接口
Map接口的使用
// 特点:1.存储键值对 2.键可以重复,值不可以重复 3.无序
// 创建Map集合时需要指定<key的类型,value的类型>
Map<String,String> map = new HashMap<>();
// 1.添加--使用put()
map.put("cn","中国");
map.put("an","美国");
map.put("vn","英国");
// map.put("cn","zhongguo"); {vn=英国, cn=zhongguo, an=美国} 键不可以重复,但是值会被替换
System.out.println(map);
//2.删除(使用key进行删除)
map.remove("cn");
System.out.println(map.size());
- 3.1遍历—keySet();
- 返回值为Set中存着键
- 在遍历键+加上值(get(键))
- 3.2遍历—entrySet();
- 4.判断–containsKey(); containsValue();
HashMap的使用
- 存储结构是哈希表
- 方法与Map接口中的方法的一样:Map的添加用put,创建集合时需要指定键和值的类型
- 最后一条语句也可以添加进来
- 与HashSet相同 可以重写 Hashcode与equals来去重
HashMap源码分析
Hashtable和Properties
- Properties继承了Hashtable
- 用的不是很多
TreeMap的使用
-
存储结构:红黑树
-
以下代码会报错
-
因为TreeMap的存储结构式红黑树:左边的节点要比右边的小
-
所以同TreeSet要实现一个Comparable接口,重写compareTo方法定制比较规则Student类对象才能存进去
-
也可以使用comparator的定制比较的方法;
f
collections的工具类
List<Integer> list = new ArrayList<>();
list.add(20);
list.add(23);
list.add(4);
list.add(15);
list.add(22);
System.out.println("排序前:"+list); //排序前:[20, 23, 4, 15, 22]
// 1.sort排序(升序)
Collections.sort(list);
System.out.println("排序后:"+list); //排序后:[4, 15, 20, 22, 23]
//2.二分查找 binarySearch 找不到就返回一个负数
int i = Collections.binarySearch(list, 100);
System.out.println(i);
//3.copy 复制
List<Integer> dest = new ArrayList<>();
// 第一个参数是目标 第二个参数是原集合
// 注意:要求两个集合的大小相同 所以用循环先添加list.size()个元素,在复制
for (int j = 0; j < list.size(); j++) {
dest.add(0);
}
Collections.copy(dest,list);
System.out.println(dest); //[4, 15, 20, 22, 23]
//4.reverse实现反转
Collections.reverse(list);
System.out.println("反转之后:"+list); // 反转之后:[23, 22, 20, 15, 4]
//5.shuffle实现打乱
Collections.shuffle(list);
System.out.println("打乱之后:"+list); //打乱之后:[22, 15, 20, 4, 23] 每次运行都不一样
//补充:list转成数组 list.toArray
Integer[] integers = list.toArray(new Integer[0]);//如果给小于list.size()的数组长度,返回之后二者相等,多则为空
System.out.println(integers.length); // 5
//使用Arrays.toString()方法输出数组
System.out.println(Arrays.toString(integers)); //[20, 15, 4, 23, 22]
//补充:数组转成集合Arrays.asList()
String[] names = {"张三","李四","王五"};
List<String> list1 = Arrays.asList(names);
System.out.println(list1);
//注意:1.转成的集合为受限制的集合,不能添加和删除
// 2.把基本类型的数组转成集合时,需要将基本类型转为包装类
总结
Java集合框架详解笔记及其代码到这就完结撒花了,喜欢的小伙伴多多点赞转发,支持哦!