上一次咱们分享的是MySQL的安装 今天让我们来看看List集合,看看你对它到底有多了解呢?
先看看今天的大纲:
一,List集合的特点
1,有序:存取元素
2,可重复性
public class Demo1 {
public static void main(String[] args) {
ArrayList list =new ArrayList<>();
//新增
list.add("zs");
list.add("ls");
list.add("ww");
list.add("zl");
//查询
System.out.println(list.get(1));
for (Object obj : list) {
System.out.println(obj);
}
运行结果:
由运行结果可以得到如上的List集合的特点
二,List集合的增删改查
public static void main(String[] args) {
ArrayList list =new ArrayList<>();
//新增
list.add("zs");
list.add("ls");
list.add("ww");
list.add("zl");
list.add("zs");
//查询
System.out.println("--------查询单个---------");
System.out.println(list.get(1));
System.out.println("--------遍历全部---------");
for (Object obj : list) {
System.out.println(obj);
}
// 修改
list.set(1, "fds");
System.out.println("----------修改后--------");
for (Object obj : list) {
System.out.println(obj);
}
// 删除
System.out.println("----------返回删除的元素----------");
Object obj2 = list.remove(1);//返回值为删除的元素
// 根据下标删除
System.out.println(obj2);
System.out.println("----------删除后--------");
for (Object obj : list) {
System.out.println(obj);
}
//根据对象删除
list.remove("ww");
System.out.println("-------根据对象删除--------");
for (Object obj : list) {
System.out.println(obj);
}
}
运行结果如下:
如何剔除集合中的奇数
此处采用了加入新集合的方法:
注意:此时很多人可能会采用循环遍历进行判断并且一边进行剔除操作删除集合中的元素,此时会发生当时改变的异常,所以我们只能加入新集合
// 1,4,6,9,11,8 剔除集合中的奇数 currentModificationException 当前改变异常
// 企业中,调用第三方接口 要针对于一些数据做过滤
// 结论:做集合元素剔除,不能在原集合中对元素进行操作,
// 我们可以再实例化一个集合,将需要的数据加入到其中
System.out.println();
ArrayList<String> list2 = new ArrayList<>();
ArrayList<String> list3 = new ArrayList<>();
list2.add("1");
list2.add("4");
list2.add("6");
list2.add("9");
list2.add("11");
list2.add("8");
System.out.println("----------原集合---------");
for (String obj : list2) {
System.out.println(obj);
}
for (String obj : list2) {
if(Integer.valueOf(obj)%2!=1) {
// list2.remove(obj);
list3.add(obj);
}
}
System.out.println("-----------剔除奇数后-------");
for (String obj : list3) {
System.out.println(obj);
}
}
运行结果如下:(此时我们就已经成功剔除了原集合中的奇数)
三,List集合的三种遍历方式
我们将三种方式合并在一起展示:
public static void main(String[] args) {
ArrayList list =new ArrayList<>();
//新增
list.add("zs");
list.add("ls");
list.add("ww");
list.add("zl");
//增强foreach循环
for (Object obj : list) {
System.out.println(obj);
}
System.out.println("----------");
//for循环
for (int i = 0; i < list.size(); i++) {
System.out.println(list.get(i));
}
System.out.println("-------------");
//迭代器遍历
Iterator it = list.iterator();
System.out.println("------判断是否有下一个,返回boolean类型------");
System.out.println(it.hasNext());//判断是否有下一个
System.out.println("--------------------");
System.out.println(it.next());//直接拿到下一个
while(it.hasNext()) {//如果还有下一个就输出
System.out.println(it.next());
}
}
四,堆栈与队列的区别
代码展示:
public static void main(String[] args) {
// 队列
// Duilie duilie =new Duilie(new LinkedList<>());
// 堆栈
Duizhan duilie =new Duizhan(new LinkedList<>());
duilie.push("zs");
duilie.push("ls");
duilie.push("ww");
duilie.push("bj");
System.out.println(duilie.pop());
System.out.println(duilie.pop());
System.out.println(duilie.pop());
System.out.println(duilie.pop());
}
}
//队列
class Duilie{
private LinkedList ll;
public Duilie(LinkedList ll) {
super();
this.ll=ll;
}
//存
public void push(Object obj) {
ll.add(obj);
}
//取
public Object pop() {
return ll.remove();
}
}
//堆栈
class Duizhan{
private LinkedList ll;
public Duizhan(LinkedList ll) {
super();
this.ll=ll;
}
//存
public void push(Object obj) {
ll.add(obj);
}
//取
public Object pop() {
return ll.removeLast();
}
}
堆栈与队列的区别在于取值:堆栈——先进后出 队列——先进先出
堆栈:
队列:
五,list集合的优化以及增长因子
1.为什么要优化list集合
当代码中出现了多次add操作,涉及到了list集合容量多次改变,这是一个十分耗性能的操作。
2.如何优化list集合
* 设定初始化容量,即可优化性能
package com.ljj.list;
import java.lang.reflect.Field;
import java.util.ArrayList;
import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader.Array;
/**
* list集合进行优化
* 当代码中出现了多次add操作,涉及到了list集合容量多次改变,这是一个十分耗性能的操作,此时通过
* 设定初始化容量,即可优化性能
*
* list集合长度是可变的,数组长度是不可变的;
* 结论1,list集合底层的数据结构是数组
* 结论2,增长因子 0.5 初始容量 10
* @author Administrator 刘俊杰
*下午7:31:54
*/
public class Demo4 {
public static void main(String[] args) throws Exception {
//String[] arr =new String[10];
//arr =new String[11];
//arr[11] ="zs";
//arr = new String[12];
//arr[12] ="zs";
ArrayList<Object> list=new ArrayList<>(100);//设定初始容量
for (int i = 0; i <200; i++) {
list.add(i);
getlen(list);
}
}
private static void getlen(ArrayList<Object> list) throws Exception {
Field f=list.getClass().getDeclaredField("elementData");
f.setAccessible(true);
Object[] elementData =(Object[]) f.get(list);
System.out.println("当前集合的元素个数:"+list.size()+";当前list集合的容量是:"+elementData.length);
}
}
运行结果:
结论:
list集合的长度是可变的,数组的长度是不可变的
list集合的初始容量为10,增长因子0.5
六,ArrayList去重以及其底层原理
方法一:
利用contains(包含)来判重,先定义一个新的集合,进行判断,把是原集合中的并且新集合中没有的元素add加入到新集合中,实际上contains本身实际上是不具备真正的判重的,只是开辟了一个新的集合来储存原集合中不重复的元素。
代码展示:
package com.ljj.list;
import java.util.ArrayList;
/**
* list集合去重底层原理
* 结论:去重引用对象时,底层调用的是对象的equals方法
* @author Administrator 刘俊杰
*下午3:03:09
*/
public class Demo5 {
public static void main2(String[] args) {
ArrayList list =new ArrayList<>();
// 新增
list.add(new Person("zs", 18));
list.add(new Person("pz·d", 29));
list.add(new Person("王心凌", 41));
list.add(new Person("ls", 22));
list.add(new Person("老六", 18));
list.add(new Person("王心凌", 41));
System.out.println(list);//6个
ArrayList listnew =new ArrayList<>();
for (Object object : list) {
if(!listnew.contains(object)) {
listnew.add(object);
}
}
System.out.println(listnew);//5个
}
public static void main(String[] args) {
ArrayList list =new ArrayList<>();
// 新增
list.add("zs");
list.add("ls");
list.add("ww");
list.add("zl");
list.add("ls");
System.out.println(list);
ArrayList listnew =new ArrayList<>();
for (Object object : list) {
if(!listnew.contains(object)) {
listnew.add(object);
}
}
System.out.println(listnew);
}
}
class Person{
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;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person() {
// TODO Auto-generated constructor stub
}
}
运行结果:
方法二:
不在代码块上进行操作,而是在实体类上进行重写equals方法。
代码展示:
package com.ljj.list;
import java.util.ArrayList;
/**
* list集合去重底层原理
* 结论:去重引用对象时,底层调用的是对象的equals方法
* @author Administrator 刘俊杰
*下午3:03:09
*/
public class Demo5 {
public static void main(String[] args) {
ArrayList list =new ArrayList<>();
// 新增
list.add(new Person("zs", 18));
list.add(new Person("pz·d", 29));
list.add(new Person("王心凌", 41));
list.add(new Person("ls", 22));
list.add(new Person("老六", 18));
list.add(new Person("王心凌", 41));
System.out.println(list);//6个
ArrayList listnew =new ArrayList<>();
for (Object object : list) {
if(!listnew.contains(object)) {
listnew.add(object);
}
}
System.out.println(listnew);//5个
}
public static void main2(String[] args) {
ArrayList list =new ArrayList<>();
// 新增
list.add("zs");
list.add("ls");
list.add("ww");
list.add("zl");
list.add("ls");
System.out.println(list);
ArrayList listnew =new ArrayList<>();
for (Object object : list) {
if(!listnew.contains(object)) {
listnew.add(object);
}
}
System.out.println(listnew);
}
}
class Person{
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;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person() {
// TODO Auto-generated constructor stub
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Person other = (Person) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
运行结果:
结论:
去重新引用对象时,底层调用的是对象的equals方法