一.集合的概述
1.数组和集合的区别
- 1.数组是定长容器,int[] arr = new int[3];
集合是可变长度容器,集合底层也是一个数组,初始开辟一个指定大小的数组,然后向数组中添加数据,如果数据将数组添加满了, 系统底层默认的分配一个更大的数组空间,原数组中内容复制到新数组中,继续向新数组中添加内容。
- 2.数组可以存储基本数据类型 double[] d = new double[5];、数组可以存储引用数据类型 String[] s = new String[3];
集合只能存储引用数据类型 如果客户的年龄为int类型,要存储在集合中,实际存储在集合中的基本数据类型对应的引用数据类型包装类
- 3.数组中的方法只能使用Object中继承来的方法,有一个属性length
集合是一个类,既可以使用Object中继承方法,类中自己封装了很多的方法
2.集合的体系结构
单列集合:容器中每一个元素,都是一个独立的个体。
(接口:所有单列集合的顶层父接口)
Collection —— List:接口、有序、有索引、可重复
—— ArrayList:底层数组结构、查询快、增删慢
—— LinkList:底层链表结构、查询慢、增删快
—— Vector:底层数组结构、查询慢、增删慢
—— Set:接口、无序、无索引、不重复
—— HashSet:底层数组+链表、查询快、增删快
双列集合:容器中一对元素,是一个整体
(接口:所有双列集合的父接口)
Map —— HashMap:二.Collection集合
1.Collection集合的介绍
- Collection是一个接口,所有单列集合的顶层父接口,来自于java.util包
- Collection兼容子接口List、Set的共有方法
- Collection是接口,不能实例化对象,需要找一个实现类,ArrayList
- Collection coll = new ArrayList();//接口的多态性,父类引用指向子类对象,左接口右实现类
2.Collection集合的常用方法
1.add(Object a):向集合末尾添加一个元素obj
2.remove(Object obj): 将obj元素从集合中删除,返回值类型Boolean类型。删除成功True、删除失败false
3.clear():清空集合,将集合中的数据删除,集合仍然存在。返回值类型void。
4.isEmpty:判断集合是否为空。返回值类型Boolean,空集合返回true,否则false。
5.contains(Object obj):判断obj元素在集合中是否存在,返回值类型Boolean,存在返回true,否则返回false
import java.util.ArrayList;
import java.util.Collection;
public class CollectionDemo {
public static void main(String[] args) {
addMethod();
removeMethod();
clearMethod();
containsMethod();
}
public static void addMethod(){
//1.创建一个集合,多态写法
Collection coll1 = new ArrayList();
//2.add(Object obj)
coll1.add("abc");
coll1.add("123");
//String重写了父类Object中toString方法,将集合中的元素打印出来
System.out.println(coll1);//[abc, 123]
Collection coll2 = new ArrayList();
Student s = new Student("张三",20);
coll2.add(s);
coll2.add(new Student("李四",20));
System.out.println(coll2);
//[com.bjzhang.demo01.Student@10f87f48, com.bjzhang.demo01.Student@b4c966a]
//Student需要重写ArrayList中toString方法 [Student{name='张三', age=20}, Student{name='李四', age=20}]
}
public static void removeMethod(){
//1.创建一个集合
Collection coll3 = new ArrayList();
//自动装箱,将int类型数据12自动封装成Integer类型
coll3.add(12);
coll3.add(-7);
coll3.add(25);
System.out.println(coll3);//[12, -7, 25]
//2.remove(Object obj)
coll3.remove(-7);
System.out.println(coll3);//[12, 25]
}
public static void clearMethod(){
//1.创建一个集合
Collection coll4 = new ArrayList();
//自动装箱,将int类型的数据自动封装成integer类型
coll4.add(12);
coll4.add(-7);
coll4.add(25);
System.out.println(coll4);//[12, -7, 25]
//2.clear()
coll4.clear();
System.out.println(coll4);//[]
//3.isEmpty()
System.out.println(coll4.isEmpty());//true
}
public static void containsMethod(){
//1.创建一个集合
Collection coll5 = new ArrayList();
//2.add(Object obj)
coll5.add("123");
coll5.add("abs");
System.out.println(coll5.contains("12"));//false
System.out.println(coll5.contains("123"));//true
}
}
public class Student {
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 Student(String name, int age) {
this.name = name;
this.age = age;
}
public Student() {
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}3.Collection集合中带有all的方法 — 返回值类型Boolean
1.A.addAll(Collection c):将集合c的全部内容,追加到集合A末尾中。
2.A.containsAll(Collection c):判断集合A中,是否包含集合C。
3.A.removeAll(Collection c):删除集合A和集合c在A中共有的元素。
4.A.retainAll(Collection c):将集合A和集合c的交集赋值给A集合。
import java.util.ArrayList;
import java.util.Collection;
public class CollectionAllMethod {
public static void main(String[] args) {
//1.A.addAll(Collection c):将集合c的全部内容,追加到集合A末尾中。
Collection coll1 = new ArrayList();
coll1.add("a");
coll1.add("b");
Collection coll2 = new ArrayList();
coll2.add("c");
coll2.add("d");
coll1.addAll(coll2);
System.out.println(coll1);//[a, b, c, d]
//2.A.containsAll(Collection c):判断集合A中,是否包含集合C。
System.out.println(coll1.containsAll(coll2));//true
//3.A.removeAll(Collection c):删除集合A和集合的交集在A中共有的元素。
Collection coll3 = new ArrayList();
coll3.add(1);
coll3.add(2);
Collection coll4 = new ArrayList();
coll4.add(1);
coll3.removeAll(coll4);//删除coll3和coll4在coll3中共有的元素
System.out.println(coll3);//[2]
//4.A.retainAll(Collection c):将集合A和集合c的交集赋值给A集合。
Collection coll5 = new ArrayList();
coll5.add(1);
coll5.add(2);
Collection coll6 = new ArrayList();
coll6.add(3);
coll6.add(4);
coll5.retainAll(coll6);
System.out.println(coll5);//[]
Collection coll7 = new ArrayList();
coll7.add(1);
coll7.add(4);
coll6.retainAll(coll7);
System.out.println(coll6);//[4]
}
}4.Collection集合的第一种遍历形式
- toArray():将集合中的所有的元素,以一个Object[]形式进行返回,返回值类型Object[]
- 为什么方法的返回值类型是Object[]?
5.Collection集合的第二种遍历形式 - 迭代器
迭代:表示从一个到下一个的过程。
迭代器:作用就是将集合中的元素,一个一个的获取到
1.iterator():获取集合的迭代器对象,返回值类型iterator,不能实例化对象
iterator 表示一个迭代器,接口,来自于java.util包
iterator 不能实例化对象,那么证明iterator()方法实际返回的接口是一个实现类对象
2.迭代器中的方法
hasNext(): 判断集合中是否有下一个元素,返回值类型Boolean类型,如果有返回true,否则返回false
next():获取当前正在迭代的元素本身,返回值类型Object类型
注意:如果集合中已经没有元素需要获取,继续使用next进行集合中元素获取,报错。没有这个元素异常,java.util.NoSuchElementException
3.迭代器的工作原理
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
public class CollectionIterator {
public static void main(String[] args) {
//1.创建一个集合
Collection c = new ArrayList();
c.add("a");
c.add("b");
c.add("c");
c.add("d");
//2.使用迭代器的方式获取集合中的元素
//(1)先获取集合的迭代器对象
Iterator it = c.iterator();//多态,左接口右实现类
while(it.hasNext()){
System.out.println(it.next());//a.b.c.d
}
}
}三.List集合
1.List集合的概述
- List 接口,来自于java.util包,是Collection的子接口
- List 接口,不能实例化对象(new 对象),找实现类 ArrayList
- List list = new ArrayList();//多态,左接口右实现类
- List接口特征:
- 有序:元素存入集合顺序与取出顺序一致
- 有索引:索引范围0--集合的长度-1
- 可重复:集合中允许存储重复元素
2.List集合的特有方法
add(int i , Object obj):将obj元素添加到集合指定i位置上,其他元素后移
remove(int i):删除索引为i的元素,返回值类型Object,返回所删元素
set(int i , Object obj): 将obj元素与索引i替换,返回值类型Object,返回被替换元素
get(int i):获取i索引位置上的元素
import java.util.ArrayList;
import java.util.List;
public class ListMethod {
public static void main(String[] args) {
addMethod();
removeMethod();
setMethod();
getMethod();
}
public static void addMethod(){
//1. 创建一个集合
List li = new ArrayList();
//2.add(int i , Object obj)
li.add(0,"a");
li.add(0,"b");
System.out.println(li);//[b, a]
li.add("c");
li.add("d");//[b,a,c,d]
li.add(2,"hello");
System.out.println(li);//[b,a,hello,c,d]
}
public static void removeMethod(){
//1. 创建一个集合
List li = new ArrayList();
//2.add(int i , Object obj)
li.add(0,"a");
li.add(0,"b");
System.out.println(li);//[b, a]
li.add("c");
li.add("d");//[b,a,c,d]
li.add(2,"hello");
//3.remove(int i):删除指定索引的元素
String s = (String)li.remove(3);
System.out.println(li);//[b, a, hello, d]
System.out.println(s);//c
}
public static void setMethod(){
List list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
Object obj = list.set(2,"QQ");
System.out.println(obj);//c
System.out.println(list);//[a, b, QQ, d]
}
public static void getMethod(){
List list = new ArrayList();
list.add("a");
list.add("b");
list.add("c");
list.add("d");
Object obj = list.get(0);//a
System.out.println(obj);
System.out.println(list.get(2));//c
//System.out.println(list.get(5));//下标索引越界异常 java.lang.IndexOutOfBoundsException
}
}3.List集合的遍历
1.List集合可以使用迭代器遍历,
2.List可以根据索引进行遍历,索引范围0-集合长度-1,get(int index)
3.求集合长度的方法 size(),返回值类型int类型
(1)数组求长度 length 属性
(2)字符串长度 length()方法
(3)集合的长度获取 size() 方法
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListFor {
public static void main(String[] args) {
//1.创建一个集合
List list = new ArrayList();
list.add(1);
list.add(2);
list.add(4);
//2.求取集合的长度
int len = list.size();
System.out.println(len);//4
//3.list集合的遍历
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));//1.2.3.4
}
//4.迭代器遍历
Iterator it = list.iterator();
while(it.hasNext()){
System.out.println("--"+it.next());
}
}
}4.并发修改异常
需求:集合["a","hello","b"],遍历集合,如果遇到集合中的元素为"hello",那么向集合中添加一个元素"world"
使用迭代器方式实现
-- ConcurrentModificationException:并发修改异常
出现异常的原因:当通过迭代器进行集合的遍历的时候,一边遍历,一边向集合中添加元素。迭代器就会爆出,并发修改异常。
对策:
for循环进行集合的遍历
ListIterator//一边遍历,一边循环
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
public class ListException {
public static void main(String[] args) {
//addEle();
//forEle();
listIteratorMethod();
}
public static void addEle(){
List list = new ArrayList();
list.add("a");
list.add("hello");
list.add("b");
System.out.println(list);
//使用迭代器遍历
//(1)获取到集合的迭代器对象
Iterator it = list.iterator();
while(it.hasNext()){
Object obj = it.next();
String s = (String)obj;
if("hello".equals(s)){
list.add("world");
}
}
System.out.println(list);//[a, hello, b]
}
public static void forEle(){
List list = new ArrayList();
list.add("a");
list.add("hello");
list.add("b");
System.out.println(list);
for (int i = 0 ; i < list.size() ; i++){//每次循环都会调用list.size(),如果集合大小改变,list.size()跟着判断
if("hello".equals((String)list.get(i)))
list.add("world");
}
System.out.println(list);//[a, hello, b, world]
}
public static void listIteratorMethod(){
List list = new ArrayList();
list.add("a");
list.add("hello");
list.add("b");
System.out.println(list);
ListIterator it = list.listIterator();
while(it.hasNext()){
Object obj = it.next();
String s = (String)obj;
if("hello".equals(s))
//list.add("world");
it.add("world");//通过迭代器添加
}
System.out.println(list);//[a, hello, world, b]
}
} 5.List的实现类
子类具有父类(接口)中所有的方法
ArrayList:底层数组结构、查询快、增删慢
LinkedList:底层是链表结构,查询慢,增删快
Vector:底层数组结构、查询慢、增删慢 从jdk1.2版本,被ArrayList取代
ArrayList数组结构
数组已满,添加元素,末尾追加
原数组元素已经装满,系统重新创建一个更大的数组,将原数组内容复制到新数组中,然后再向新数组中添加元素。
增加跟删除慢
查找快(索引)
LinkedList链表结构
查询慢,每个元素必须查询到,牵手式
增删快,只需要改变指针指向即可练习1:分析以下需求,并用代码实现
(1)生成10个1-100之间的随机整数,存入一个List集合 --> 解决去重问题
(2)编写方法对List集合进行排序(由大到小)
(3)然后利用迭代器遍历集合元素并输出
(4)如,15 18 20 40 46 65 70 75 91import java.util.*;
public class HomeWork1 {
public static void main(String[] args) {
//1.创建随机数对象
Random r = new Random();
//2.创建一个集合list,装10个不重复的随机数
ArrayList<Integer> list = new ArrayList();
//3.创建一个集合list100,装1-100的整数,用于挑选不重复的随机数
ArrayList<Integer> list100 = new ArrayList();
for(int i = 1 ; i <= 100 ; i++){
list100.add(i);
}
//4.将10个随机的不重复数,放到list集合中
for(int i = 0 ; i < 10 ; i++){
//生成1-100的随机数
int count = r.nextInt(100)+1;
int result = list100.get(count - 1);//生成随机数1对应list100(0)
if(result != 0){//这个随机数没有被挑选过
list.add(count);
list100.set(count-1,0);//将刚刚挑选过的置为0
}else{//这个随机数被挑选过
i--;
}
}
/*Collections.sort(list);
System.out.println(list);//[10, 18, 21, 33, 40, 41, 64, 81, 83, 95]
*/
//5.利用数组中选择排序法
up(list);
// System.out.println(list);//[2, 11, 15, 25, 26, 28, 45, 54, 59, 63]
//6.使用迭代器遍历list集合
Iterator<Integer> it = list.iterator();
while(it.hasNext()){
System.out.print(it.next()+" " );//7 14 34 37 40 54 67 75 79 95
}
}
public static void up(ArrayList<Integer> list){
//5.利用数组中选择排序法
for(int i = 0 ; i < list.size() ; i++ ){//0索引元素和后面所有元素比较
for(int j = i + 1 ; j < list.size() ; j++){
if(list.get(i) > list.get(j)){
int temp = list.get(i);
list.set(i,list.get(j));//list中第i个索引替换为后面
list.set(j,temp);
}
}
}
}
}练习2:分析以下需求,并用代码实现
(1)定义List集合,存入多个字符串,其中包含三个连续的"def"
(2)删除集合中字符串"def"
(3)然后利用迭代器遍历集合元素并输出 import java.util.*;
public class HomeWork2 {
public static void main(String[] args) {
//1.创建一个list集合,存放String类型的字符串
ArrayList<String> list = new ArrayList<>();
//2.向集合中添加字符串,包含三个连续的"def"
list.add("abc");
list.add("a");
list.add("def");
list.add("def");
list.add("def");
list.add("hello");
list.add("123");
list.add("QQ");
System.out.println(list);//[abc, a, def, def, def, hello, 123, QQ]
//3.Collections接口,带有ALL方法,A.removeAll(Collection c) 删除A集合和c集合在A中共有的元素
ArrayList<String> listDef = new ArrayList<>();
listDef.add("def");
list.removeAll(listDef);
System.out.println(list);//[abc, a, hello, 123, QQ]
}
}练习3.分析以下需求,并用代码实现
(1)定义List集合,存入多个字符串
(2)删除集合中包含0-9数字的字符串(只要字符串包含)
(3)然后利用迭代器遍历集合元素并输出 import java.util.ArrayList;
import java.util.Iterator;
public class HomeWork3 {
public static void main(String[] args) {
//1.创建一个List集合
ArrayList<String> list = new ArrayList<>();
//2.向集合中添加元素
list.add("1abc");
list.add("he7llo");
list.add("world12");
list.add("799");
list.add("ef");
//3.remove():表示在迭代过程中,将目前正在迭代的元素进行删除,不会发生并发修改异常
Iterator<String> it = list.iterator();
while(it.hasNext()){
String s = it.next();
//判断字符串中是否包含数字
//正则表达式[^0-9]{1,} --> 匹配没有数字的字符串
if(!s.matches("[^0-9]{1,}")){//字符串中包含数字
it.remove();
}
}
System.out.println(list);//[ef]
}
}练习4.定义一个方法:给定一个数组,将数组内容转换成一个字符串
例如:数组为int[] arr = {1,2,3},输出字符串为[1,2,3]
本题使用StringBuilder拼接字符串实现public class HomeWork4 {
public static void main(String[] args) {
int [] arr = {-23,99,56,7};
try{
System.out.println(function(arr));//2.int [] arr = {}; []
//3.int [] arr = {-23,99,56,7}; [-23,99,56,7]
}catch(Exception ex){
ex.printStackTrace();//1.int [] arr = null; java.lang.Exception: 数组不能为null
}
}
public static String function(int[] arr) throws Exception{
//1.arr数组不能为null
if(arr == null){
throw new Exception("数组不能为null");//编译异常一旦出现必须声明或处理
}
//2.arr数组如果没有元素,是一个空数组[]
if(arr.length == 0){
return "[]";
}else{//3.数组中有元素
//需要将arr数组中每一个元素都获取到
StringBuilder sb = new StringBuilder("[");
for(int i = 0 ; i < arr.length ; i++){
if(i==arr.length-1){
//最后一个元素需要拼接]
sb.append(arr[i]+"]");
}else {//除最后元素,其他元素后拼接逗号
sb.append(arr[i] + ",");
}
}
return sb.toString();
}
}
}练习5.分析以下需求,并用代码实现
(1)定义数字字符串数组{"010","3223","666","7890987","123123"}
(2)判断该数字字符串数组中数字字符串是否对称
(3)打印该数组中对称字符串的个数分析:
1.将字符串中的每一个字符获取到
2.7890987 需要两个索引,比较对应索引位置
public class HomeWork5 {
public static void main(String[] args) {
//1.创建一个字符串数组
String[] ss = {"010","3223","666","7890987","123123"};
//2.获取每一字符串
for(String ele : ss){
//3.将获取到的字符串中的每一个字符获取到
char[] ch = ele.toCharArray();
//4.判断ch数组中存储的元素是否对称存在
//设定标志,默认值为TRUE
boolean flag = true;
for(int i = 0,j = ch.length-1 ; i < j ; i++,j--){
if(ch[i]!=ch[j]){
flag = false;
break;
}
}
if(flag == true){
System.out.print(ele+" ");//010 3223 666 7890987
}
}
}
}练习6.编写Person类,类中具有姓名,年龄,性别,地址
属性值如下列表,将每个人的信息放入集合中,遍历集合,在main函数中输出每个人的信息
姓名 年龄 性别 地址
张三 23· 男 河南
李四 45 男 河南
王五 34 女 山西
赵六 22 男 北京
田七 33 女 北京import java.util.ArrayList;
public class HomeWork6 {
public static void main(String[] args) {
//1.先创建一个存储Person对象的集合
ArrayList<Person> list = new ArrayList<>();
//2.向集合中添加Person对象
list.add(new Person("张三",23,"男","河南"));
list.add(new Person("李四",45,"男","河南"));
list.add(new Person("王五",34,"女","山西"));
list.add(new Person("赵六",22 ,"男","上海"));
list.add(new Person("田七",33,"女","北京"));
//增强for遍历list
for(Person p:list){
System.out.println(p.getName()+"--"+p.getAge()+"--"+p.getSex()+"--"+p.getAddr());
}
}
}