一 关于集合框架
1 集合是Java提出的用来进行多个数据存储的"容器",数组也具备这样的功能,
2 由于数组一旦创建长度固定,且只能存放一种数据类型,不够灵活,Java提出更灵活,存放任意的数据类型的容器也就是集合
3 集合和数组的异同点
相同点:都是用来存储多个数据类型的容器
不同点:存储的灵活性
① 长度: 数组一旦创建长度固定;集合可以灵活存储
② 数据类型: 数据可存放指定的一种数据类型,既可以是基本数据类型也可以是引用数据类型;集合只能存放任意的引用数据类型(如果赋值基本数据类型,底层以基本数据类型的包装类存储,自动装箱的形式完成)
二 集合框架的分类
1 单列集合-将数据进行一个一个的存储
2 双列集合-基于 Key 与 Value 的结构存储数据
3 单列集合存储特点以及具体实现类底层存储
① 存储特点
Collection接口: 既可以存储重复值,也可以存储不重复值;既可以有序,也可以无序
List接口: 有序不唯一
Set接口: 无序且唯一
Queue接口: 先进先出 队列式存储
② 实现类底层存储模式
ArrayList类: 底层基于动态数组存储
LinkedList类: 底层基于双链表存储
TreeSet类: 底层基于二叉树存储
HashSet: 底层基于哈希码值存储
三 单列集合
1 ArrayList类
// 可调整大小的数组的实现List接口
Class ArrayList<E>
< E> – 表示泛型
① 泛型的含义: 泛指的任意的引用数据类型
② 泛型使用的格式: <字母> – 字母一般是任意一个,必须得大写
java中规定的泛型字母 | 含义 |
---|---|
E | Element,表示集合中存储元素的类型 |
K | KEY,表示Map中键的类型 |
V | VALUE,表示Map集合中值的类型 |
R | Result,表示方法的返回值类型 |
? | 表示不确定的任意一种类型 |
T | Type,存储的类型 |
③ 使用泛型的好处:提高集合存储数据的安全性;一旦集合使用泛型,等效于数组;实际开发中,一般在集合使用的时候,必须配合泛型使用
2 创建集合
ArrayList对象有初始值;长度是10;可以进行扩容;扩容的倍数是1.5
public class ArrayListTest {public static void main(String[] args) {ArrayList list=new ArrayList();// 直接打印集合对象,显示集合中所有元素System.err.println(list);}
}
3 增加元素
// 在集合的尾部追加指定的元素
public boolean add(E e)// 将指定的元素插入到集合的指定位置上
public void add(int index ,E e)// 例子
public class ArrayListTest {public static void main(String[] args) {ArrayList<Object> list=new ArrayList<Object>();list.add("qq");list.add(13);list.add(false);list.add('@');// 指定下标添加元素list.add(2,5);list.add("qq");list.add(0,23);System.err.println(list);//[23, qq, 13, 5, false, @, qq]}
}
4 删除元素
// 清空集合中所有数据,但是保留集合结构
public void clear()// 移除指定位置上的元素,并且返回该元素
public E remove(int index)// 将指定元素从集合中移除(如果存在)
public boolean remove(E e)// 例子
public class ArrayListTest {public static void main(String[] args) {ArrayList<Object> list=new ArrayList<Object>();list.add("qq");list.add(13);list.add(false);list.add('@');// 指定下标添加元素list.add(2,5);list.add("qq");list.add(0,23);System.err.println(list);// [23, qq, 13, 5, false, @, qq]// 删除指定元素时若元素类型是整数或字符型,需将值传递为元素对象进行删除// 因为可能会将传递的值认为是下标,造成数组下标越界// 值转对象:类型强转 (包装类)值System.err.println("移除元素5"+list.remove((Integer)5));// 移除元素5trueSystem.err.println(list);// [23, qq, 13, false, @, qq] 删除成功返回 trueSystem.out.println("移除位置3上的元素:"+list.remove(3));// 移除位置3上的元素:false(返回元素本身)System.out.println(list);list.clear();System.out.println("清空后的list"+list);}
}
5 修改元素
// 使用指定的元素修改指定位置上的原有元素,将原有的元素返回
public E set(int index,E e )// 例子
public class ArrayListTest {public static void main(String[] args) {ArrayList<Object> list=new ArrayList<Object>();list.add("qq");list.add(13);list.add(false);list.add('@');// 指定下标添加元素list.add(2,5);list.add("qq");list.add(0,23);System.err.println(list);// [23, qq, 13, 5, false, @, qq]System.out.println("用!替换1位置上的元素"+list.set(1,"!"));// 返回指定位置上的元素 用!替换1位置上的元素qqSystem.out.println("替换后"+list);// 替换后[23, !, 13, 5, false, @, qq]}
}
6 查询元素
// 获取集合指定位置上的元素
public E get(int index)// 获取指定元素在集合中第一次出现的位置,如果不存在返回-1
public int indexOf(E e)// 获取指定元素在集合中最后一次出现的位置,如果不存在返回-1
public int lastIndexOf(E e)// 获取集合元素的真实个数
public int size()// 获取集合中指定范围内的所有元素,不包含结束位置
public List<E> subList(int beginIndex,int endIndex)// 例子
public class ArrayListTest {public static void main(String[] args) {ArrayList<Object> list=new ArrayList<Object>();list.add("qq");list.add(13);list.add(false);list.add('@');// 指定下标添加元素list.add(2,5);list.add("qq");list.add(0,23);System.err.println(list);// [23, qq, 13, 5, false, @, qq]System.out.println("集合长度"+list.size());// 集合长度7System.out.println("2位置上的元素"+list.get(2));// 2位置上的元素13System.out.println("qq第一次出现的位置"+list.indexOf("qq"));// qq第一次出现的位置1System.out.println("qq最后一次出现的位置"+list.lastIndexOf("qq"));// qq最后一次出现的位置6System.out.println("[1,3)范围内的元素"+list.subList(1,3));// [1,3)范围内的元素[qq, 13]}
}
7 判别元素
// 判断指定的元素是否是集合中的元素
public boolean contains(E e)// 例子
public class ArrayListTest {public static void main(String[] args) {ArrayList<Object> list=new ArrayList<Object>();list.add("qq");list.add(13);list.add(false);list.add('@');// 指定下标添加元素list.add(2,5);list.add("qq");list.add(0,23);System.err.println(list);// [23, qq, 13, 5, false, @, qq]System.out.println("@在集合中吗"+list.contains('@'));// @在集合中吗true}
}
8 Collections类 – 操作所有单列集合工厂类
// 获取指定单列集合中元素的最大值
public static E max(Collection<E> c)// 获取指定单列集合中元素的最小值
public static E min(Collection<E> c)// 给指定的List集合进行默认的升序排序
public static void sort(List<E> list)// 将指定的多个散数据(引用数据类型),同时存放到List 集合中,Arrays类提供
public static List<T> asList( T ..... t)// 例子
public class ArrayListTest {public static void main(String[] args) {ArrayList<Integer> list=new ArrayList<Integer>();list.add(13);list.add(7);list.add(45);list.add(2);list.add(2,5);list.add(0,23);System.err.println(list);// [23, 13, 7, 5, 45, 2]Collections.sort(list);System.out.println("排序后"+list);// 排序后[2, 5, 7, 13, 23, 45]System.out.println("最大"+Collections.max(list));System.out.println("最小"+Collections.min(list));// 最大45 最小2}
}// 将任意的多个引用数据类型同时存储在List集合中
public class ArrayListTest {public static void main(String[] args) {List<Object> list = Arrays.asList("qwer", 'e', 456, Math.PI, true);System.err.println(list);// [qwer, e, 456, 3.141592653589793, true]// list是接口对象,因此不能直接调用接口中的抽象方法完成操作// 需将list集合的数据放到ArrayList中,通过ArrayList对象调用方法完成操作ArrayList<Object> als=new ArrayList<Object>();for (Object o: list) {als.add(o);}als.add("asdwd");System.out.println(als);// [qwer, e, 456, 3.141592653589793, true, asdwd]}
}
9 LinkedList类 – 创建集合
// 双向链表
Class LinkedList<E>// 创建集合
public LinkedList()
10 LinkedList 与 ArrayList 集合中的一致方法,使用效果也一致,参考ArrayList同名方法
11 增加元素
// 将指定的元素插入到链表的头部
public void addFirst(E e)//将指定的元素查入到链表的尾部
public void addLast(E e)// 例子
public class ArrayListTest {public static void main(String[] args) {LinkedList<Integer> ll=new LinkedList<>();ll.add(12);ll.add(122);ll.add(142);ll.add(2,22);System.err.println(ll);// [12, 122, 22, 142]ll.addFirst(-11);ll.addLast(-22);System.err.println(ll);// [-11, 12, 122, 22, 142, -22]}
}
12 删除元素
// 移除链表中头部位置上的元素
public E removeFirst()// 移除链表中尾部位置上的元素
public E removeLast()// 例子
public class ArrayListTest {public static void main(String[] args) {LinkedList<Integer> ll=new LinkedList<>();ll.add(12);ll.add(122);ll.add(142);ll.add(2,22);System.err.println(ll);// [12, 122, 22, 142]ll.removeFirst();System.err.println(ll);// [122, 22, 142]}
}
四 java的数据存储方式
1 数据存储方式:实质上就是集合型数据在jvm虚拟机中存取的操作
2 分类
① 队列式存储: 先进先出,类似于吸管
存: LinkedList类 – addFirst()
取: LinkedList类 – removeLast()
② 堆栈式存储 : 先进后出
存:LinkedList类中 – addFirst()
取:LinkedList类中 – removeFirst()
代码演示 – 堆栈内存存储方式
public class PriStack<T> {// 定义私有化变量LinkedListprivate LinkedList<T> ll;// 定义当前类有参构造器,参数是用户传递的LinkedList对象public PriStack(LinkedList<T> ll){this.ll=ll;}// 存数据public void save(T t){ll.addFirst(t);}// 取数据public T gain(){return ll.removeFirst();}// 显示集合元素public void show(){System.err.println(ll);}// 取元素个数public int size(){return ll.size();}
}public class PriStackTest {public static void main(String[] args) {PriStack<String> ps=new PriStack<String>(new LinkedList<String>());ps.save("this a");ps.save("this b");ps.save("this c");ps.show();// [this c, this b, this a]while (ps.size()>0){System.out.println(ps.gain());}//this c//this b//this a}
}
3 泛型的应用
① 泛型可以使用的位置 : 类 和 类成员 (一般成员方法)
② 泛型使用的前提: 定义的类或类成员完成对数据的存取操作时
五 HashSet类
1 创建对象
// 此类实现Set接口
public class HashSet<E>// 创建对象
public HashSet()
2 Set集合是无序的散列表,元素的位置相对不稳定,故Set集合中摒弃List集合中所有有关位置的方法,没有关于位置操作的方法;其余与List同名方法参照List集使用
public class play {public static void main(String[] args) {HashSet<Object> hs=new HashSet<>();hs.add("132");hs.add(213);hs.add('*');hs.add("dw");hs.add(5.5);System.out.println(hs);// [132, dw, 213, 5.5, *]}
}
3 例子
// 向集合存放十个数,以升序排序的方式显示,同时显示最大最小值
public class play {public static void main(String[] args) {ArrayList<Integer> list=new ArrayList<Integer>();for (int i = 0; i < 10; i++) {// 注意优先级问题list.add((int)(Math.random()*100));}System.err.println("排序前"+list);Collections.sort(list);System.err.println("排序后"+list);System.err.println(Collections.max(list));System.err.println(Collections.min(list));}
}// 方式二
public class play {public static void main(String[] args) {HashSet<Integer> hashSet=new HashSet<Integer>();while (hashSet.size()<10){hashSet.add((int) (Math.random()*100));}System.err.println(hashSet);System.err.println(Collections.max(hashSet));System.err.println(Collections.min(hashSet));}
}
六 迭代器
1 迭代表示产品的更新换代,在集合中所谓的迭代就是操作(存和取)指定集合中的元素
2 数组对于元素的存取操作的方式
① 存
for(int i=0;i<数组名.length;i++){数组名[i]=值;
}
② 取
//当需要操作元素下标的时候 -- 使用普通for循环
for(int 1=0; i<数组名.length;i++){变量=数组名[i];
}
//当需要直接操作数组元素的时候 -- 使用增强for (forEach)
for(数据类型 变量名 : 数组名){操作变量;
}
3 对于List集合-单列集合元素存取操作
① 存数据 – 普通for循环
for(int i = 0; i<数值;i++){集合对象名.add(E e);
}
//推荐使用while原因集合长度不限,因此很少指定长度
while(true){集合对象名.add(E e);if(判断条件){break;}
}
② 取数据
//方式一:根据元素下标获取元素 普通for
for(int i= 0 ;i<集合对象名.size();i++){对象=集合对象名.get(i);
}
//方式二:直接操作元素 增强for
for(类 对象 : 集合名){操作对象;
}
//方式三: 迭代器,java封装好的一个接口Iterator迭代接口
Iterator<集合泛型的类型> it = 集合对象名.iterator();//获取迭代器对象
while(it.hasNext()){//判断下一个位置是还有元素对象=it.next();//获取集合中的元素
}
4 Set集合中对元素的存和取操作
① 存数据
//由于Set集合没有位置,因此只能使用while循环添加数据
while(true){集合对象名.add(E e);if(判断条件){break;}
}
② 取数据
for(类 对象: 集合名){操作对象;
}
5 关于迭代器(单列)
hasNext方法的详解 – 游标指针操作原理
通过集合对象获取迭代器对象,通过迭代器对象调用hasNext(),此时游标指针创建,默认停放的位置是-1,表示没有获取到元素;通过while循环启动游标指针,在指定的单列集合中移动
在迭代器中对该方法限定移动范围[0,集合对象名.size())
例子
// 迭代器只操作单列集合
public class play {public static void main(String[] args) {HashSet<Integer> hashSet=new HashSet<Integer>();while (hashSet.size()<10){hashSet.add((int) (Math.random()*100));}System.err.println(hashSet);// 通过单列集合对象调用iterator()方法获取迭代器对象,有迭代器对象才能调用迭代器方法Iterator<Integer> it=hashSet.iterator();// 通过迭代器对象调用方法,判断集合中下一个位置上是否还有元素,有则继续while (it.hasNext()){// 元素存在,通过迭代器对象获取元素赋值给i,显示Integer i=it.next();// 显示大于60的元素if(i>60){System.err.println(i);}}}
}