目录
集合--->容器
代码
运行
Java集合API
单列集合
Collectio接口
List接口实现类
ArrayList 数组实现
概念
代码
运行
代码
ArrayList方法
代码
运行
LinkedList 链表实现
概念
代码
运行
Vector 数组实现
概念
代码
运行
List接口集合迭代
for循环
代码
运行
增强for循环
代码一
代码二
运行
迭代器一
代码
运行
编辑
迭代器二
代码
运行
set接口
HashSet
概念
代码
运行
编辑
代码
运行
HashSet自定义类型
代码
运行
TreeSet
概念
代码
运行
TreeSet自定义类型
代码
运行
Set接口集合迭代
Collection接口
Collections类
代码
运行
可变参数
代码
运行
集合--->容器
数组:同一种类型,长度固定,不可变,每个元素都有索引,索引从0开始。
数组在实际使用时有哪些不方便?
长度不可变
1、现实中程序运行时数据量是可以改变的,需要能够满足可变的需求
2、有的时候想存储不可重复的数据,有的时候想对元素进行排序。
例:ArrayList中数组长度可自动扩容
代码
package com.ffyc.javacollection;
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
ArrayList arrayList = new ArrayList();
arrayList.add("abc");
arrayList.add("abc");
arrayList.add("abc");
arrayList.add("abc");
arrayList.add("abc");
arrayList.add("abc");
arrayList.add("bbb");
arrayList.add("ccc");
arrayList.add("abc");
arrayList.add("abc");
arrayList.remove("bbb");
System.out.println(arrayList);
}
}
运行
所以Java中为我们提供了许多不同特征的容器类
学习Java给我们提供的不同的容器类,来实现更为丰富的数据存储。
Java集合API
集合体系概述 Java的集合框架是由很多接口、抽象类、具体类组成的,都位于java.util包中。
单列集合
Collectio接口
Collection 接口-定义了存取一组对象的方法,其子接口Set和List分别定义 了存储方式。
List接口实现类
ArrayList 数组实现
概念
ArrayList<String> arrayList = new ArrayList<>();
底层数组实现,查询的效率最快
中间删除,添加的效率低
数组的空间利用率可能会浪费
代码
List接口实现类
add
ArrayList 是可以保存重复元素的,底层是数组实现,添加的元素类型可以是任意类型的
package com.ffyc.javacollection.list;
import java.util.ArrayList;
public class ArraysListDemo1 {
public static void main(String[] args) {
ArrayList alist = new ArrayList();
alist.add(1);
alist.add("c");
alist.add('c');
for (int i = 0;i<alist.size();i++){
Object object = alist.get(i);
if(object instanceof String){
String s = (String) object;
System.out.println(s.length());
}
}
}
}
运行
代码
然集合中默认是可以添加任意数据类型的,但是后续处理时,会出现类型转换问题
所以Java中 集合类都支持自定义类型(泛型 把类型当作参数传递)
ArrayList<String> 定义时为集合中可以存储的数据设计一个类型,必须是类类型
好处:一个集合中只能存储一种相同数据类型,后续处理方便了
package com.ffyc.javacollection.list;
import java.util.ArrayList;
public class ArraysListDemo1 {
public static void main(String[] args) {
ArrayList<Integer> arrayList1 = new ArrayList<>();
arrayList1.add(10);//自动装箱
ArrayList<String> arrayList2 = new ArrayList<>();
arrayList2.add("hhh");
}
}
ArrayList方法
代码
底层是一个数组,默认长度是10,当数组装满时,会自动扩容,,扩容到原来的1.5倍
package com.ffyc.javacollection.list;
import javax.net.ssl.SSLServerSocket;
import java.util.ArrayList;
public class ArraysListDemo2 {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
//向末尾添加元素,会自动扩容
arrayList.add("hhh");
arrayList.add("iii");
arrayList.add("jjj");
arrayList.add("sss");
arrayList.add("kkk");
arrayList.add("hhh");
arrayList.add("iii");
arrayList.add("jjj");
arrayList.add("kkk");
arrayList.add("hhh");
arrayList.add("iii");
arrayList.add("jjj");
arrayList.add("kkk");
//向指定的位置添加元素,位置从0开始 到size(实际装入的元素个数)
arrayList.add(11,"sss");
System.out.println(arrayList);
//根据元素的内容删除数据,只删除匹配的第一个元素
arrayList.remove("sss");
System.out.println(arrayList);
//删除并返回指定位置上元素
String s = arrayList.remove(10);
System.out.println(s);
System.out.println(arrayList);
//是否包含指定元素
System.out.println(arrayList.contains("hhh"));
//获取指定位置的元素(底层时数组,获取元素的速度是最快的)
System.out.println(arrayList.get(3));
//获取指定元素首次出现的位置
System.out.println(arrayList.indexOf("jjj"));
//从后开始查找
System.out.println(arrayList.lastIndexOf("hhh"));
//判断集合中的元素是否为空 为空--->true 否则--->false
System.out.println(arrayList.isEmpty());
//替换指定位置的元素
System.out.println(arrayList.set(1, "ccc"));
//返回数组的实际(装有元素)长度(个数)
System.out.println(arrayList.size());
System.out.println(arrayList);
//清空集合
arrayList.clear();
System.out.println(arrayList);
}
}
运行
LinkedList 链表实现
概念
LinkedList<String> linkedlist = new LinkedList<>();
查询慢
中间增加和删除速度快,元素不需要移动,只需要改变地址值
不存在空间浪费
代码
List接口实现类
LinkedList
底层是链表实现,每一个数据封装在一个Node对象中。
package com.ffyc.javacollection.list;
import java.util.LinkedList;
public class LInkedListDemo {
public static void main(String[] args) {
LinkedList<String> linkedlist = new LinkedList<>();
linkedlist.add("a");
linkedlist.add("b");
linkedlist.add("c");
linkedlist.add("d");
//向链表末尾添加元素
linkedlist.add("d");
//向指定的位置添加元素
linkedlist.add(2, "e");
System.out.println(linkedlist);
//从链表中获取指定位置的元素(从头或者尾开始查找,效率低于ArrayList)
System.out.println(linkedlist.get(3));
System.out.println(linkedlist.contains("b"));
System.out.println(linkedlist.remove("a"));
System.out.println(linkedlist.remove(2));
//删除并返回第一个结点内容
System.out.println(linkedlist.removeFirst());
//删除并返回最后一个结点内容
System.out.println(linkedlist.removeLast());
System.out.println(linkedlist.isEmpty());
System.out.println(linkedlist.size());
linkedlist.set(1, "s");
System.out.println(linkedlist);
//清空
linkedlist.clear();
System.out.println(linkedlist);
}
}
运行
Vector 数组实现
概念
Vector<Integer> vector = new Vector<>();
代码
Vector
数组实现
是多线程安全的
package com.ffyc.javacollection.list;
import java.util.Vector;
public class VectorDemo {
public static void main(String[] args) {
Vector<Integer> vector = new Vector<>();
vector.add(1);
vector.add(2);
vector.add(3);
vector.add(4);
vector.add(1);
vector.add(1);
vector.add(1);
vector.add(1);
vector.add(1);
vector.add(1);
vector.add(1);
System.out.println(vector);
}
}
运行
List接口集合迭代
for循环
代码
package com.ffyc.javacollection.list;
import java.util.ArrayList;
public class ArraysListDemo3 {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("a");
arrayList.add("a");
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("d");
arrayList.add("e");
arrayList.add("f");
//1、for循环
for (int i = 0; i < arrayList.size(); i++) {
if(arrayList.get(i).equals("a")){
//for循环的时候,是支持从for循环中删除元素的,但是删除后,后面的元素会向前移动,需要控制索引
arrayList.remove(i);
i--;
}
}
System.out.println(arrayList);
}
}
运行
增强for循环
增强for循环中不可进行删除元素,不能使用remove(),使用会报错
代码一
package com.ffyc.javacollection.list;
import java.util.ArrayList;
public class ArraysListDemo3 {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("a");
arrayList.add("a");
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("d");
arrayList.add("e");
arrayList.add("f");
//2、增强for循环
for(String s:arrayList){
if(s.equals("a")){
arrayList.remove("a");//增强for循环时,删除元素的过程中不允许删除元素
}
}
System.out.println(arrayList);
}
}
代码二
package com.ffyc.javacollection.list;
import java.util.ArrayList;
public class ArraysListDemo3 {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("a");
arrayList.add("a");
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("d");
arrayList.add("e");
arrayList.add("f");
//增强for循环l 方式1:根据键找值
for(String s:arrayList){
System.out.println(s);
}
}
}
运行
迭代器一
代码
package com.ffyc.javacollection.list;
import java.util.ArrayList;
import java.util.Iterator;
public class ArraysListDemo3 {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("a");
arrayList.add("a");
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("d");
arrayList.add("e");
arrayList.add("f");
//迭代器1
Iterator<String> it = arrayList.iterator();
while(it.hasNext()){
String n = it.next();
if(n.equals("a")){
it.remove();//迭代器中删除的方法,底层有一计数器,删除元素时,计数器会自动的回退
}
}
System.out.println(arrayList);
}
}
运行
迭代器二
ListIterator():默认是从第0个位置开始的,只能从前向后遍
ListIterator(index):从指定的位置开始向前/向后遍历
代码
package com.ffyc.javacollection.list;
import java.util.ArrayList;
import java.util.ListIterator;
public class ArraysListDemo3 {
public static void main(String[] args) {
ArrayList<String> arrayList = new ArrayList<>();
arrayList.add("a");
arrayList.add("a");
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("d");
arrayList.add("e");
arrayList.add("f");
ListIterator<String> listIterator = arrayList.listIterator(arrayList.size());//size = 最大索引+1
while(listIterator.hasPrevious()){
String s = listIterator.previous();
System.out.println(s);
}
}
}
运行
set接口
HashSet
概念
HashSet<Student> stu = new HashSet<>();
底层使用的是HashMap
元素存储是无序的
去除重复元素的方式
hashCode() equals()
代码
Set接口:不能存储重复元素
HashSet
元素是无序的(既不是添加顺序,也不是按元素的自然顺序)
package com.ffyc.javacollection.set;
import java.util.HashSet;
public class HashSetDemo1 {
public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("a");
set.add("x");
set.add("p");
set.add("k");
set.add("i");
set.add("e");
set.add("p");
System.out.println(set);
System.out.println(set.contains("a"));
System.out.println(set.isEmpty());
set.remove("p");
System.out.println(set);
System.out.println(set.size());
set.clear();
System.out.println(set);
}
}
运行
代码
向HashSet中是添加元素时,是如何判断元素是否重复的
添加元素时 调用equals()判断,效率低(一个一个字符判断)
底层用到HsahCode() 和 equals() 方法
puwvzwogvc 用内容计算一个hash值(整数),用hash值比较速度快
但是hash是不安全的,有可能内容不同,计算的hash值相同
当hash值相同时,调用equals方法,判断内容是否相等
这样效率提高了 也保证安全了
package com.ffyc.javacollection.set;
import java.util.HashSet;
public class HashSetDemo2 { public static void main(String[] args) {
HashSet<String> set = new HashSet<>();
set.add("a");
set.add("x");
set.add("puwvzwogvc");//500
set.add("通话");
set.add("重地");
set.add("e");
set.add("puwvzwogvc");//500
System.out.println(set);
}
}
运行
HashSet自定义类型
代码
package com.ffyc.javacollection.set;
public class Student extends Object implements Comparable<Student>{
private int num;
private String name;
public Student(int num, String name) {
this.num = num;
this.name = name;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
if (num != student.num) return false;
return name.equals(student.name);
}
@Override
public int hashCode() {
int result = num;
result = 31 * result + name.hashCode();
return result;
}
@Override
public String toString() {
return "Student{" +
"num=" + num +
", name='" + name + '\'' +
'}';
}
}
添加时,判断时会调用类中hashCode()计算hash值,类中没有hashCode(),会调用父类hashCode()
Object类中的public native int hashCode();native本地方法(操作系统提供的)
所以只要是new出来的,调用Object类中hash值,是内容地址,肯定不相同
如果我们想要对象中的内容相等就判定为重复元素,就必须在我们的类中重写hashCode() equals() 用对象中的内容来计算hash值
package com.ffyc.javacollection.set;
import java.util.HashSet;
public class HashSetDemo3 {
public static void main(String[] args) {
HashSet<Student> stu = new HashSet<>();
Student stu1 = new Student(001, "钟白");
Student stu2 = new Student(002, "逸帆");
Student stu3 = new Student(003, "路先生");
Student stu4 = new Student(001, "钟白");
stu.add(stu1);
stu.add(stu2);
stu.add(stu3);
stu.add(stu4);
System.out.println(stu);
}
}
运行
TreeSet
概念
TreeSet<Integer> tset = new TreeSet<>();
树型结构
有序(是根据值的自然顺序排序)
去重 排序使用的是compareTo()
代码
Set 不能存储重复元素
TreeSet
底层是树型结构 有一个根节点,每一个结点有两个子节点,大的元素向右放,小的元素向左放
添加进来的元素可以排序(有序的 不是添加的顺序,是元素的自然顺序)
package com.ffyc.javacollection.set;
import java.util.TreeSet;
public class TreeSetDemo1 {
public static void main(String[] args) {
TreeSet<Integer> tset = new TreeSet<>();
tset.add(3);
tset.add(1);
tset.add(5);
tset.add(4);
tset.add(3);
tset.add(2);
tset.size();
tset.contains(2);
//删除并返回第一个元素
System.out.println(tset.first());
tset.isEmpty();
//删除指定内容的一个元素
tset.remove(3);
//删除并返回最后一个元素
System.out.println(tset.pollLast());
System.out.println(tset);
tset.clear();
System.out.println(tset);
}
}
运行
TreeSet自定义类型
代码
package com.ffyc.javacollection.set;
public class Student extends Object implements Comparable<Student>{
private int num;
private String name;
public Student(int num, String name) {
this.num = num;
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"num=" + num +
", name='" + name + '\'' +
'}';
}
/*
提供的排序比较的方法
*/
@Override
public int compareTo(Student o) {
return this.num-o.num;
}
}
package com.ffyc.javacollection.set;
import java.util.TreeSet;
public class TreeSetDemo2 {
public static void main(String[] args) {
TreeSet<Student> tset = new TreeSet<>();
Student stu1 = new Student(001, "钟白");
Student stu2 = new Student(002, "逸帆");
Student stu3 = new Student(003, "路先生");
Student stu4 = new Student(001, "钟白");
tset.add(stu2);
tset.add(stu4);
tset.add(stu3);
tset.add(stu1);
System.out.println(tset);
}
}
运行
Set接口集合迭代
Set接口集合是有序的,没有下标,无法使用for循环,其他与collenction一致
遍历方式
增强for循环
迭代器遍历
Collection接口
Collection 接口-定义了存取一组对象的方法,其子接口Set和List分别定义 了存储方式。
Collections类
Collections是集合类的工具类,与数组的工具类Arrays类似
代码
集合工具类
package com.ffyc.javacollection;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
public class CollenctionsDemo {
public static void main(String[] args) {
ArrayList<Integer> arrayList1 = new ArrayList<>();
arrayList1.add(1);
arrayList1.add(5);
//把一个数组添加到集合中
Collections.addAll(arrayList1,3,7,2,6 );
//排序
Collections.sort(arrayList1);
//二分查找(必须有序)如果找到,返回元素所在位置
System.out.println(Collections.binarySearch(arrayList1, 1));
//交换位置
Collections.swap(arrayList1, 3, 1);
System.out.println(arrayList1);
//逆序
Collections.reverse(arrayList1);
System.out.println(arrayList1);
//随机顺序排放
Collections.shuffle(arrayList1);
System.out.println(arrayList1);
//填充 集合中的元素全部一致化
Collections.fill(arrayList1, 1);
System.out.println(arrayList1);
ArrayList<Integer> arrayList2 = new ArrayList<>();
arrayList2.add(1);
arrayList2.add(3);
//把第二个参数的集合元素复制到第一个集合参数的集合中,第一个集合的size必须大于等于第二个集合size
Collections.copy(arrayList1, arrayList2);
System.out.println(arrayList2);
System.out.println(arrayList1);
}
}
运行
可变参数
类型 ... 参数名 可变长度的参数,本质是数组
一个参数列表中,只能有一个可变长度的参数,而且必须放在参数列表的末尾
代码
package com.ffyc.javacollection;
import java.util.Arrays;
public class CollenctionsDemo {
public static void main(String[] args) {
test(1,2,3);
}
public static void test(int b,int ...a){
System.out.println(Arrays.toString(a));
}
}