集合框架
集合简介
集合的概念
集合是存储对象的容器,面向对象语言对事物的体现都是以对象的形式,所以为了方便对多个对象的存储和操作,集合是存储对象最常用的一种方式。
集合中可以存储任意类型的对象, 而且长度可变。在程序中有可能无法预先知道需要多少个对象, 那么用数组来装对象的话, 长度不好定义, 而集合解决了这样的问题。
集合和数组的区别
数组和集合类都是容器。但是数组长度是固定的,集合长度是可变的。一个数组中存储数据类型是单一的,一个集合中可以存储任意类型的对象。
集合类的特点:长度是可变的,可以存储不同类型的数据。
数组的缺点:存储类型单一的数据容器,操作复杂(数组一旦声明好不可变)。
集合的结构
Java集合框架位于java.util包中,提供了一套性能优良、使用方便的接口和类。
ArrayList集合
ArrayList是有序,不唯一数据的集合
ArrayList有下标,下标从0开始
语法:
ArrayList 集合名 = new ArrayList();
ArrayList跟LinkedList的区别:
-
ArrayList底层是数组结构(初始化长度是10,扩容因子是1.5) 查询快,增删慢
-
LinkedList底层是链表结构,增删快,查询慢
集合的增删改查
import java.util.ArrayList;
public class ArrayListTest1 {
public static void main(String[] args) {
// 1.创建ArrayList对象-创建ArrayList集合容器
ArrayList arrayList = new ArrayList();
/**
* 2.向集合中存数据
*/
arrayList.add(10);
arrayList.add(3.14);
arrayList.add('a');
arrayList.add("hello");
arrayList.add(true);
// 3.查
System.out.println(arrayList.get(1));
// 4.改
System.out.println(arrayList.get(4));
arrayList.set(4, false);
System.out.println(arrayList.get(4));
// 5.删除,删除集合元素后,集合的长度会变小
arrayList.remove(2);
// 获取集合的长度
int size = arrayList.size() ;
System.out.println(size);
}
}
集合是一个对象容器,因此存储到集合中的所有元素都是对象,而不是基本数据类型。原理是存储到集合中的元素的基本数据类型,会先自动装箱为对应的包装类再向上转型为为Object类型
因为Object类是所有类的父类,可以表示所有对象的数据类型,所以集合中可以存储任意类型的数据。
public class ArrayListTest2 {
public static void main(String[] args) {
// 1.创建ArrayList对象-创建ArrayList集合容器
ArrayList arrayList = new ArrayList();
/*
* 1.把int类型的数字10自动装箱为Integer类型
* 2.Integer类型的数字向上转型为Object类型
*/
// Integer m = 10;
// Object obj = m;
arrayList.add(10);
/**
* Object obj = "hello";
*/
arrayList.add("hello");
// 2.查询
// 包装类给基本数据类型赋值或运算时,会先 转化为基本数据类型再参与运算
int num = (Integer) arrayList.get(0);
String str = (String) arrayList.get(1);
System.out.println(num);
System.out.println(str);
}
}
集合的其他方法
public class ArrayListTest3 {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
arrayList.add(10);
arrayList.add("hello");
// 6.判断集合是否包含某个元素
boolean isContains = arrayList.contains("hello");
System.out.println(isContains);
// 7.把集合转为数组
Object [] arr = arrayList.toArray();
// 8.把数组转集合
list = Arrays.asList(arr);
// 9..直接输出集合对象
System.out.println(arrayList);
// 10.清除集合中的所有元素
arrayList.clear();
System.out.println(arrayList);
}
}
import java.util.ArrayList;
public class UserTest {
public static void main(String[] args) {
User user1 = new User("张三");
User user2 = new User("李四");
User user3 = new User("甲");
User user4 = new User("乙");
ArrayList list = new ArrayList();
list.add(user1);
list.add(user2);
list.add(user3);
list.add(user4);
// 查看集合中的数据
// User类创建的对象只能调用父类Object中被重写的方法,而set和get方法是User特有的方法,不能直接调用
// 必须先把Object类型的对象强转成User类才能继续调用set和get方法
User obj1 =(User) list.get(0);
System.out.println(obj1.getName());
User obj4 =(User) list.get(3);
System.out.println(obj4.getName());
}
}
集合的泛型
/**
* 泛型的作用
* 1.限制集合中能够存入的数据的类型,可以降低出错率
* 2.当我们去查看集合元素的时候,省略强转
* 泛型的特点:泛型只能用引用数据类型表示
*/
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(10);
list.add(123);
//查看集合元素
int n = list.get(0);
//创建user对象
User user1 = new User("赵日天");
//向集合中添加数据
ArrayList<User> userList = new ArrayList<User>();
userList.add(user1);
//查看集合中的数据
User u = userList.get(0);
System.out.println(u);
HashSet集合
存储无序且唯一的数据,数据不能重复
集合没有下标,增删改查功能根据元素删除,而不是下标
HashSet集合的增删改查
/**
* HashSet存储无序且唯一的数据
* HashSet集合没有下标
*/
//1.创建hashSet集合对象
HashSet<Integer> hashSet = new HashSet<Integer>();
//2.增
hashSet.add(10);
hashSet.add(5);
hashSet.add(200);
hashSet.add(5);
System.out.println(hashSet);
//3.删--根据元素删除
hashSet.remove(200);
System.out.println(hashSet);
//4.判断是否包含某个元素
boolean isContains = hashSet.contains(50);
System.out.println(isContains);
//5.清空集合元素
// hashSet.clear();
System.out.println(hashSet);
//6.获取集合的长度
int size = hashSet.size();
System.out.println("集合的长度为"+size);
/**
* HashSet集合的遍历
* 因为HashSet没有下标,不能使用普通for循环遍历
*/
for(int m:hashSet) {
System.out.println(m);
}
/**
* HashSet转ArrayList
* 使用ArrayList的构造方法进行转换
*/
ArrayList<Integer> list = new ArrayList<Integer>(hashSet);
System.out.println(list);
/**
* ArrayList集合转HashSet
*/
HashSet<String> hashSet2 = new HashSet<String>(list2);
System.out.println(hashSet2);
HashSet集合的应用
特点:
-
存储无序且唯一的数据
-
没有下标
去重: 有一堆数据存储在list集合中,要求去除其中重复的数据
hashset集合的去重原理:
-
比较对象的hashCode,如果对象的hashCode不一样,则不去重;
-
如果镀锌的hashCode一样,再调用对象的equals方法比较两个对象的值,如果值不一样,则不去重,如果值一样,则去重。
public class HashSetTest2 {
public static void main(String[] args) {
/**
* 使用hashSet对ArrayList去重
*/
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
list.add(1);
HashSet<Integer> set = new HashSet<Integer>(list);
System.out.println(set);
System.out.println(set.size());//2
User user1 = new User("赵日天");
User user2 = new User("赵日天");
User user3 = new User("赵日天");
User user4 = new User("赵日天");
/**
* hashset集合的去重原理
* 比较对象的hashCode,如果对象的hashCode不一样,则不去重;
* 如果镀锌的hashCode一样,再调用对象的equals方法比较两个对象的值,如果值不一样,则不去重,如果值一样,,则去重。
*/
HashSet<User> hashSet = new HashSet();
// hashSet集合中新增了四个值一样的对象,但四个对象的hashCode不一样,因此不会去重,集合长度依旧为4
hashSet.add(user1);
hashSet.add(user2);
hashSet.add(user3);
hashSet.add(user4);
System.out.println(hashSet.size());//4
HashSet<String> strSet = new HashSet();
// strSet集合中新增了三个对象,其中对象"Aa"和对象"BB"的hashCode虽然一样,但此时会调用对象的equals方法来比较两个对象的值,值不一样,因此不去重。
strSet.add("Aa");
strSet.add("BB");
strSet.add("Aa");
System.out.println(strSet.size());//2
}
}
HashMap集合
Map是一种依照键(key)存储元素的容器,键(key)很像下标,在List中下标是整数。在Map中键(key)可以使任意类型的对象。Map中不能有重复的键(Key),每个键(key)都有一个对应的值(value)。一个键(key)和它对应的值构成map集合中的一个元素。
import java.util.HashMap;
/**
* HashMap集合,通过键值对来进行相应操作
* Key(键)
* Value(值)
* 允许使用 null 值和 null 键
*/
public class MapTest1 {
public static void main(String[] args) {
// 1.创建HashMap集合对象
// 键的类型通常设为String,值的类型通常设为Object,Object类是所有类的父类,因此集合可以输入任何类型的值
HashMap<String,Object> map = new HashMap<String,Object>();
// 2.新增元素
map.put("name","张三");
map.put("age",30);
System.out.println(map);
// 3.删除元素,通过键来删除一对数据
map.remove("name");
// 4.修改,方法和新增元素一样
map.put("age",20);
// 5.查询元素,通过键来查询
Object value = map.get("name");
System.out.println(value);
// 6.获取长度
int size = map.size();
// 7.判断map集合是否包含指定的键
boolean flag1 = map.containsKey("age");
System.out.println(flag1?"包含":"不包含");
// 8.判断map集合是否包含指定的值
boolean flag2 = map.containsValue("张三");
System.out.println(flag2?"包含":"不包含");
System.out.println(map);
// 9.清空所有数据
map.clear();
System.out.println(map);
}
}
HashMap集合的遍历
import java.util.HashMap;
import java.util.Iterator;
import java.util.Set;
/**
* HashMap集合的循环遍历
*/
public class MapTest2 {
public static void main(String[] args) {
HashMap<String,String> map = new HashMap();
map.put("三国演义","罗贯中");
map.put("水浒传","施耐庵");
map.put("红楼梦", "曹雪芹");
map.put("西游记","吴承恩");
// 输出的值顺序是无序的,说明HashMap集合是个无序集合
System.out.println(map);
// map集合遍历
// 1.获取map集合的所有的键,keySet方法的返回值是一个Set集合,因此需要定义一个Set类型的集合来接收
Set<String> keys = map.keySet();
// 2.对Set集合进行遍历,因为HashMap集合没有下标,因此只能使用增强for循环来遍历、
// 通过循环来得到每一个键
for(String key :keys) {
// 3.再通过键查询值
String value = map.get(key);
System.out.println(key+":"+value);
} System.out.println("=========================");
// 方法二:迭代器配合while循环
// 1.获取到map集合的所有键
Set<String> keys2 = map.keySet();
Iterator<String> iterator = keys2.iterator();
while(iterator.hasNext()) {
// 从迭代器中获取到键
String key2 = iterator.next();
// 通过键获取到map集合的值
String value2 = map.get(key2);
// 输出
System.out.println(key2+":"+value2);
}
}
}
Collections集合工具类
Collections和Collection不同,前者是集合的操作类,后者是集合接口。
package com.woniuxy.map;
import java.util.ArrayList;
import java.util.Collections;
/**
* 区分:
* Collection是集合的顶级接口,而Collections是集合工具类,一般对ArrayList集合进行相关操作
*/
public class CollectionsTest {
public static void main(String[] args) {
ArrayList<Integer> list = new ArrayList<Integer>();
// 向ArrayList集合中新增元素
list.add(2);
list.add(90);
list.add(45);
list.add(38);
list.add(27);
// 因为ArrayList集合重写了toString方法,所以打印对象名直接输出集合元素的值
System.out.println(list);
// 1.使用集合工具类对集合进行排序--升序(只有list集合才能排序)
Collections.sort(list);
System.out.println("升序排序"+list);
// 2.反转。Collections工具类没有降序排序的方法,但有反转方法。降序排序可以先升序后再将集合反转
Collections.reverse(list);
// 3.找最大值
int max = Collections.max(list);
System.out.println("最大值:"+max);
// 4.找最小值
int min = Collections.min(list);
System.out.println("最小值:"+min);
}
}
集合遍历的总结
List集合的遍历
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(5);
list.add(2);
list.add(20);
list.add(15);
list.add(30);
//普通for循环遍历list集合--通过下标遍历
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("---------------------------");
//增强for循环遍历list集合--不通过下标遍历
for(int n:list) {
System.out.println(n);
}
System.out.println("------------------开始----------------");
//迭代器
//1.获取到集合的迭代器
Iterator<Integer> iterator = list.iterator();
//2.使用while循环配合迭代器进行遍历
/**
* iterator.hasNext()判断集合是否有元素
*/
while(iterator.hasNext()) {
//查询迭代器中的元素
int m = iterator.next();
System.out.println(m);
}
Set集合的遍历
//1.创建hashSet集合对象
HashSet<Integer> hashSet = new HashSet<Integer>();
//2.增
hashSet.add(10);
hashSet.add(5);
hashSet.add(200);
//使用增强for循环遍历
for(int m:hashSet) {
System.out.println(m);
}
System.out.println("----------开始---------");
//使用迭代器遍历
//1.获取到set集合的迭代器
Iterator<Integer> iterator = hashSet.iterator();
//2.使用while循环遍历迭代器
/**
* hasNext()判断有没有下一个元素
*/
while(iterator.hasNext()) {
//next()查询出下一个元素
int n = iterator.next();
System.out.println(n);
}
Map集合的遍历
Map<String, String> map = new HashMap<String, String>();
map.put("三国演义", "罗贯中");
map.put("红楼梦", "曹雪芹");
map.put("水浒传", "施耐庵");
map.put("西游记", "吴承恩");
//map集合的遍历-方式一
//1.获取到map集合中所有的键
Set<String> keys = map.keySet();
//2.对set集合遍历
for(String k:keys) {
//3通过键查询值
String v = map.get(k);
System.out.println(k+":"+v);
}
System.out.println("-------------------");
//map集合的遍历-方式二
//1.获取到map集合中所有的键
Set<String> keys2 = map.keySet();
//2.获取到set集合的迭代器
Iterator<String> iterator = keys2.iterator();
while(iterator.hasNext()) {
//从迭代器中获取到键
String key = iterator.next();
//通过键获取到map集合中的值
String value = map.get(key);
//输出
System.out.println(key +":"+value);
}
集合排序
普通排序
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(5);
list.add(2);
list.add(20);
list.add(15);
list.add(30);
System.out.println(list);
//1.使用集合的工具类对集合排序--升序(只有list集合能排序)
Collections.sort(list);
System.out.println("升序排序"+list);
接口排序
1.在需要排序的对象的类上实现接口Comparable
2.重写接口中的compareTo方法
3.定义排序的规则
4.调用集合工具类的sort方法进行排序
package com.woniuxy.coll1.sort;
public class User implements Comparable<User>{
private String name;
private int 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;
}
public User() {
super();
}
public User(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
/**
* 返回值可以有三种结果
* 正数 0 负数
* 1 0 -1
*/
@Override
public int compareTo(User o) {
if(this.age > o.getAge()) {
return -1;
}else if(this.age < o.getAge()) {
return 1;
}else {
return 0;
}
}
}
public class TestSort {
public static void main(String[] args) {
// 1.创建user对象 有姓名,年龄2个属性
User user1 = new User("赵日天", 500);
User user2 = new User("李杀神", 800);
User user3 = new User("王诛魔", 300);
User user4 = new User("刘斩仙", 200);
//2.创建ArrayList集合
ArrayList<User> list = new ArrayList<User>();
list.add(user1);
list.add(user2);
list.add(user3);
list.add(user4);
Collections.sort(list);;
//遍历
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
}
}
比较器
public class User {
private String name;
private int 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;
}
public User(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
}
// 1.创建user对象 有姓名,年龄2个属性
User user1 = new User("赵日天", 500);
User user2 = new User("李杀神", 800);
User user3 = new User("王诛魔", 300);
User user4 = new User("刘斩仙", 200);
// 2.创建ArrayList集合
ArrayList<User> list = new ArrayList<User>();
list.add(user1);
list.add(user2);
list.add(user3);
list.add(user4);
/**
* 比较器 Comparator
* 1.创建Comparator的子类对象,使用匿名内部类实现
*/
Comparator<User> c = new Comparator<User>() {
@Override
public int compare(User o1, User o2) {
if(o1.getAge()>o2.getAge()) {
return -1;
}else if(o1.getAge()<o2.getAge()) {
return 1;
}else {
return 0;
}
}
};
//2 使用比较器排序(重点)
Collections.sort(list, c);
// 遍历
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
null关键字
null(空值) 表示什么都没有,没有消耗内存空间
引用数据类型的变量都可以赋null值
list集合set集合都可以存储null值
map集合允许null值null键,可以有一个null键,多个null值
//1.所有的引用数据类型都可以赋null
String str = null;
//2.List集合可以存储null
List<String> list = new ArrayList<String>();
list.add(null);
list.add(null);
System.out.println(list);
//3.Set集合可以存储null
Set<String> set = new HashSet<String>();
set.add(null);
set.add(null);
System.out.println(set);
//4.Map集合也可以存储null
Map<String, String> map = new HashMap<String, String>();
map.put(null, null);
map.put("name", null);
map.put("age", null);
System.out.println(map);
null引起的异常
当一个引用数据类型的变量值为null是,容易出现空指针异常
比如:
/**
* 当变量str赋null值时,我们认为这个变量没有值
*/
String str = null;
System.out.println(str.length());
List<String> list =null;
list.add("hello");
System.out.println(list.size());
User user = null;
System.out.println(user.getAge());
//判断一个变量是否是null值
System.out.println(str == null);
System.out.println(list == null);
System.out.println(user == null);
return关键字
作用一: 返回值
public static int fun1() {
return 10;
}
作用二: 结束方法的执行,return后面的语句不会执行,直接结束方法。
public static void fun2(int n) {
if(n == 5) {
System.out.println("*************");
return;
}
System.out.println("-----------------");
}
作用三: 结束循环
public static void fun3() {
for(int i=0;i<10;i++) {
System.out.println("============="+i);
if(i==5) {
return;
}
}
}