1、数组扩容
package com.qf.pan.list;/*
* @author pyh
* @date 2020/12/2 0002 上午 9:57
* @version 1.0
* @since JDK1.8_241
数组扩容
有三种方式:
① int[] arr2=new int[arr1.length*2] //新数组长度
for(int i=0;i<arr1.length;i++){ //复制
arr2[i]=arr1[i];
}
② int[] arr2=java.util.Arrays.copyOf(原数组名,新数组长度);
③ int[] arr2=new int[arr1.length*2]
System.arraycopy(原数组名,起始下标,新数组名,起始下标,复制长度);
*/
import java.util.Arrays;
public class Demo01 {
public static void main(String[] args) {
String[] strs = {"a","b","c","d"};
//1、创建新的数组 二进制 右移1位
//strs.length>>1即 4 -->100 >>1 = 10 -->2
String[] newStr = new String[(strs.length>>1)+strs.length];//扩容1.5倍
//2、把原来的数组值赋值给新的数组
for (int i = 0; i < strs.length; i++) {
newStr[i] = strs[i];
}
//3、把对象指向新的数组
strs = newStr;
System.out.println(Arrays.toString(strs));
}
}
2、集合概念
- 对象的容器,定义了对多个对象进行操作的常用方法。可实现数组的功能。
- 位置:java.util.*;
- 数组长度固定,集合长度不固定。
- 数组可以存储基本类型和引用类型,集合只能存储引用类型。
2.1 Collection集合
Collection父接口:
- 特点:代表一组任意类型的对象,无序、无下标。
常用方法:
方法 | 描述 |
---|---|
boolean add(Object obj) | 添加一个对象数据 |
boolean addAll(Collection c) | 将一个集合中的所有对象添加到此集合中 |
void clear() | 清空此集合中的所有对象 |
boolean contains(Object o) | 检查此集合中是否包含o对象 |
boolean equals(Object o) | 比较此集合是否与指定对象相等 |
boolean isEmpty() | 判断此集合是否为空 |
boolean remove(Object o) | 在此集合中移除o对象 |
int size() | 返回此集合中的元素个数 |
Object[] toArray() | 将此集合转换成数组 |
案例演示:保存简单数据。
public class TestCollection1 {
public static void main(String[] args) {
//创建集合
Collection collection=new ArrayList();
//1添加元素
collection.add("苹果");
collection.add("西瓜");
collection.add("榴莲");
System.out.println("元素个数:"+collection.size());
System.out.println(collection);
//2删除元素
//collection.remove("榴莲");
//collection.clear();
//System.out.println("删除之后:"+collection.size());
//3遍历元素【重点】
//3.1使用增强for
System.out.println("------3.1使用增强for-------");
for (Object object : collection) {
System.out.println(object);
}
//3.2使用迭代器(迭代器专门用来遍历集合的一种方式)
//hasNext();有没有下一个元素,
//next();获取下一个元素
//remove();删除当前元素
System.out.println("------3.2使用增强for-------");
Iterator it=collection.iterator();
while(it.hasNext()) {
String s=(String)it.next();
System.out.println(s);
//不能使用collection删除方法,因为遍历同时不能使用集合删除方法,否则出现并发修改异常。
//可以使用迭代器的删除方法
//collection.remove(s);
//it.remove();
}
System.out.println("元素个数:"+collection.size());
//4判断
System.out.println(collection.contains("西瓜"));
System.out.println(collection.isEmpty());
}
}
2.2List集合
2.2.1List接口
- 特点:有序、有下标、元素可以重复。
- 继承Collection接口。
常用方法:
方法 | 描述 |
---|---|
void add(int index, Object o) | 在index位置插入对象o。 |
boolean addAll(int index, Collection c) | 将一个集合中的元素添加到此集合中的index位置。 |
Object get(int index) | 返回集合中指定位置的元素。 |
List subList(int fromIndex, int toIndex) | 返回fromIndex和toIndex之间的集合元素。 |
案例演示:
public class TestList {
public static void main(String[] args) {
//先创建集合对象
List list=new ArrayList();
//1添加元素
list.add("苹果");
list.add("小米");
list.add(0, "华为");
System.out.println("元素个数:"+list.size());
System.out.println(list.toString());
//2删除元素
//list.remove("苹果");
// list.remove(0);
// System.out.println("删除之后:"+list.size());
// System.out.println(list.toString());
//3遍历
//3.1使用for遍历
System.out.println("-----3.1使用for遍历-----");
for(int i=0;i<list.size();i++) {
System.out.println(list.get(i));
}
//3.2使用增强for
System.out.println("-----3.2使用增强for-----");
for (Object object : list) {
System.out.println(object);
}
//3.3使用迭代器
Iterator it=list.iterator();
System.out.println("-----3.3使用迭代器-----");
while(it.hasNext()) {
System.out.println(it.next());
}
//3.4使用列表迭代器 ,和Iterator的区别,ListIterator可以向前或向后遍历,添加、删除、修改元素
ListIterator lit=list.listIterator();
System.out.println("------使用列表迭代器从前往后-------");
while(lit.hasNext()) {
System.out.println(lit.nextIndex()+":"+lit.next());
}
System.out.println("------使用列表迭代器后往前-------");
while(lit.hasPrevious()) {
System.out.println(lit.previousIndex()+":"+lit.previous());
}
//4判断
System.out.println(list.contains("苹果"));
System.out.println(list.isEmpty());
//5获取位置
System.out.println(list.indexOf("华为"));
}
}
2.3 List实现类中的ArrayList
- 数组结构实现,查询快、增删慢。
- JDK1.2版本、线程不安全。
- ArrayList存储结构是数据,查找、遍历效率高。
- LinkedList存储结构是双向链表,删除、添加效率高。
package com.qf.pan.list;/*
List:有序可重复的集合
ArrayList:底层是动态数组,第一次存储的时候数组长度为0
存储的数据超过数组长度,数组就会自动扩容为原来的1.5倍
LinkedList:底层是双向链表,不存在索引,理论上长度无限
老师总结:
ArrayList vs LinkedList
1.ArrayList底层是动态数组,LinkedList底层是双向链表
2.查询ArrayList更快
3。中间插入、删除,LinkedList需要从头开始查询到插入的对象的位置,
ArrayList可以快速定位,但是插入对象后,后续的对象索引通通发生改变
*/
import java.util.ArrayList;
public class Demo02 {
public static void main(String[] args) {
ArrayList list = new ArrayList();
//添加add
list.add("abc");
list.add(11);
list.add(23);
list.add(1);
//for循环遍历再输出
for (int i = 0; i < list.size(); i++) {
//get()通过索引获取对象
System.out.println(list.get(i));
}
System.out.println("------修改-------");
//修改set
list.set(1,"s");
//for循环遍历再输出
for (int i = 0; i < list.size(); i++) {
//get()通过索引获取对象
System.out.println(list.get(i));
}
System.out.println("-------删除对象---------");
//删除remove --根据对象
list.remove("abc");
//for循环遍历再输出
for (int i = 0; i < list.size(); i++) {
//get()通过索引获取对象
System.out.println(list.get(i));
}
System.out.println("-------删除对象为 的数据---------");
//删除对象为23的数据
list.remove(new Integer(23));
//for循环遍历再输出
for (int i = 0; i < list.size(); i++) {
//get()通过索引获取对象
System.out.println(list.get(i));
}
}
}
2.4 LinkedList
- 链表结构实现,增删快,查询慢。
- JDK1.2版本、线程不安全。
package com.qf.pan.list;
//LinkedList:底层是双向链表,不存在索引,理论上长度无限
import java.util.LinkedList;
public class Demo03 {
public static void main(String[] args) {
LinkedList list = new LinkedList();
//添加add
list.add("abc");
list.add(11);
list.add(23);
list.add(1);
//for循环遍历再输出
for (int i = 0; i < list.size(); i++) {
//get()通过索引获取对象
System.out.println(list.get(i));
}
System.out.println("------修改-------");
//修改set
list.set(1,"s");
//for循环遍历再输出
for (int i = 0; i < list.size(); i++) {
//get()通过索引获取对象
System.out.println(list.get(i));
}
System.out.println("-------删除对象---------");
//删除remove --根据对象
list.remove("abc");
//for循环遍历再输出
for (int i = 0; i < list.size(); i++) {
//get()通过索引获取对象
System.out.println(list.get(i));
}
System.out.println("-------删除对象为 的数据---------");
//删除对象为23的数据
list.remove(new Integer(23));
//for循环遍历再输出
for (int i = 0; i < list.size(); i++) {
//get()通过索引获取对象
System.out.println(list.get(i));
}
}
}
2.5 Vector
数组结构实现,查询快、增删慢。
JDK1.0版本,线程安全、运行效率比ArrayList较慢。
package com.qf.pan.list;
//Vector:底层是数组,线程安全的集合
import java.util.Enumeration;
import java.util.Vector;
public class Demo04 {
public static void main(String[] args) {
Vector vector = new Vector();
vector.add("a");
vector.add(11);
vector.addElement("b");
vector.addElement("c");
//遍历 --跟Demo06中迭代器的写法类似
Enumeration element = vector.elements();
//判断是否还包含对象
while (element.hasMoreElements()){
//获取下一个对象
System.out.println(element.nextElement());
}
}
}
2.6 Stack
Stack:模拟堆栈的集合,特点是后进先出,用完即删,线程安全的集合。
package com.qf.pan.list;/*
* @author pyh
* @date 2020/12/2 0002 下午 2:45
* @version 1.0
* @since JDK1.8_241 Last Int First Out
Stack:模拟堆栈的集合,特点是后进先出(LIFO),用完即删,线程安全的集合
*/
import java.util.Stack;
public class Demo05 {
public static void main(String[] args) {
Stack stack = new Stack();
stack.push("w");
stack.push("a");
stack.push("s");
stack.push("d");
System.out.println(stack.size());//stack集合的个数
//遍历
//empty()判断是否为null
while (!stack.empty()){
//pop()从集合的顶部获取对象并返回
//研究pop()底层
System.out.println(stack.pop());
}
System.out.println(stack.size());
}
}
3、集合的遍历
集合的遍历:有四种方法,分别是for循环、foreach、迭代器和lambda。
package com.qf.pan.list;
//集合的遍历
import java.util.ArrayList;
import java.util.Iterator;
public class Demo06 {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add("a");
list.add(111);
list.add("d");
System.out.println("----for循环-------");
//for循环
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("----foreach循环-------");
//foreach --本质上用的时候相当于用迭代器
for (Object item:list) {
System.out.println(item);
}
System.out.println("-----迭代器--------");
//迭代器 while循环中的next()要么定义一个,要么在输出的时候写,二者选其一
Iterator it = list.iterator();//Iterator --迭代器的一个类
//hasNext()判断是否有下一个元素
while (it.hasNext()){
//next()获取下一个元素并返回
Object obj = it.next();
System.out.println(obj);
}
//第二种写法
/*while (it.hasNext()){
//next()获取下一个元素并返回
System.out.println(it.next());
}*/
System.out.println("-----lambda-------");
//lambda表达式
list.forEach(obj -> System.out.println(obj));
}
}
4、泛型
4.1 泛型概念
概念:Java泛型是指JDK1.5中引入的一个新特性,其本质是参数化类型,把类型作为参数传递。
常见形式有泛型类、泛型接口、泛型方法。
语法:
- <T,…> T称为类型占位符,表示一种引用类型。
优点:
- 提高代码的重用性
- 防止类型转换异常,提高代码的安全性
package com.qf.pan.list;/*
* @author pyh
* @date 2020/12/2 0002 下午 4:31
* @version 1.0
* @since JDK1.8_241
泛型:约束集合中存储对象的类型
*/
import com.qf.pan.entity.User;
import java.util.ArrayList;
import java.util.Iterator;
public class Demo07 {
public static void main(String[] args) {
ArrayList<User> list = new ArrayList();
list.add(new User(1,"小红"));
list.add(new User(2,"小蓝"));
list.add(new User(3,"小黄"));
//list.add("a"); 与上面的方法不一样
//遍历
System.out.println("-----foreach-----");
for (User user: list) {
System.out.println(user);
}
System.out.println("-----迭代器-------");
Iterator<User> it = list.iterator();
while (it.hasNext()){
User user = it.next();
System.out.println(user);
}
}
}
注:1、泛型只能使用引用类型。 2、不同泛型类型对象之间不能相互赋值。
4.2 泛型集合
- 参数化类型、类型安全的集合,强制集合元素的类型必须一致。
- 特点:
- 编译时即可检查,而非运行时抛出异常。
- 访问时,不用类型转换(拆箱)。
- 不同泛型之间的引用不能相互赋值,泛型不存在多态。
public class TestArrayList2 {
public static void main(String[] args) {
ArrayList<String> arrayList=new ArrayList<String>();
arrayList.add("xxx");
arrayList.add("yyy");
// arrayList.add(10);
// arrayList.add(20);
for (String string : arrayList) {
System.out.println(string);
}
ArrayList<Student> arrayList2=new ArrayList<Student>();
Student s1=new Student("刘德华", 20);
Student s2=new Student("郭富城", 22);
Student s3=new Student("梁朝伟", 18);
arrayList2.add(s1);
arrayList2.add(s2);
arrayList2.add(s3);
Iterator<Student> it=arrayList2.iterator();
while(it.hasNext()) {
Student s=it.next();
System.out.println(s.toString());
}
}
}