List
1.1 list接口的简介
1.2 list实现子类
ArrayList:
线程不安全,查询速度快,底层用的是数组,增删慢
LinkedList:
线程不安全,链表结构,增删速度快,查询慢
Vector:
线程安全,但速度慢,已被ArrayList替代
1.3 list的遍历方法
迭代器注意事项:
迭代器在Collcection接口中是通用的
迭代器的next方法返回值类型是Object,如果需要所以要记得类型转换。
1.4练习
1.使用ArrayList存储基本数据类型对象,并遍历
2.使用ArrayList存储字符串对象,并遍历
import java.util.ArrayList; /* * 使用ArrayList存储基本数据类型对象,并遍历 */ public class Demo1 { public static void main(String[] args) { // Colletion // List ArrayList list = new ArrayList(); list.add(10);//此处发生的是自动装箱int --> Integer 1.5 list.add(true);//Boolean list.add(3.14);//Double list.add('a');//Character /* * * * list.add(Integer.valueOf(10)); list.add(Boolean.valueOf(true)); list.add(Double.valueOf(3.1400000000000001D)); list.add(Character.valueOf('a')); */ for (Object object : list) { System.out.println(object); } } }
练习2:
3.使用ArrayList存储自定义类型对象,并遍历
4.使用ArrayList实现字符串的去重
import java.util.ArrayList; /* * 使用ArrayList存储自定义类型对象,并遍历 * * * 快速生成Getters Setters : * alt + shift + s : --> Generate getters and setters -->空参构造方法 -->带参构造方法 */ 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() { super(); // TODO Auto-generated constructor stub } public Student(String name, int age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "Student [name=" + name + ", age=" + age + "]"; } } public class Demo3 { public static void main(String[] args) { ArrayList list = new ArrayList(); // 创建自定义对象 Person s1 = new Person("张三", 15); Person s2 = new Person("李四", 25); Person s3 = new Person("王五", 20); // 添加到集合 list.add(s1); list.add(s2); list.add(s3); //添加匿名对象 list.add(new Person("tom", 16)); for (Object obj : list) { Person s = (Person) obj;//元素类型确切是Student才能强转成功 // System.out.println(s.getName() + "--" + s.getAge()); // System.out.println(s.toString()); System.out.println(s);//间接调用toString方法 } } }
import java.util.ArrayList; /* * 使用ArrayList实现字符串的去重 * * 思路: * 创建一个新的集合. * 把原集合中的元素取出,在新集合中进行判断.如果包含,就不添加,如果不包含,就添加. * 遍历完,新集合中就是去重之后的结果. * * 不创建新集合实现去重: * 思路:从前往后比较,注意删除元素后,后面的元素会向前移位 * * */ public class Demo4 { public static void main(String[] args) { /* ArrayList list = new ArrayList(); list.add("abc"); list.add("abc"); list.add("abc2"); list.add("abc2"); list.add("world"); //创建一个新集合 ArrayList list2 = new ArrayList(); for (Object obj : list) { //contains if(!list2.contains(obj)){ list2.add(obj); } } //打印新集合内容 System.out.println(list2);//调用toString方法 */ ArrayList list = new ArrayList(); list.add("abc"); list.add("abc"); list.add("abc"); list.add("abc2"); list.add("abc2"); list.add("abc2"); list.add("abc2"); list.add("abc3"); list.add("abc3"); list.add("abc3"); list.add("abc3"); list.add("abc3"); //从前往后比较,注意删除元素后,后面的元素会向前移位 /* for(int i = 0;i<list.size() - 1;i++){ for(int j = i + 1;j<list.size();j++){ if(list.get(i).equals(list.get(j))){ list.remove(j); j--; } } } */ //2.从后往前比较 for(int i = 0;i<list.size();i++){ for(int j = list.size() - 1;j>i;j--){ if(list.get(i).equals(list.get(j))){ list.remove(j); } } } System.out.println(list); } }
import java.util.ArrayList; /* *重写equals方法原则 * 1.先进行非空判断 * 2.转换成同类型 * 3.对所有的成员变量进行比较,所有的成员变量都相同的情况下才是相同的对象 * * */ 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; } public Person() { super(); } public Person(String name, int age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } @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方法,告诉虚拟机什么情况下两个对象才是相同的对象 * 步骤:非空判断 --> 类型转换 --> 成员变量比较 */ /* @Override public boolean equals(Object obj) { // return true; //所有的成员变量都相同的情况下,两个对象才是相等的. if(obj == null){ return false; } //把传入的参数进行类型转换,同类才能比 Person p = (Person)obj; int age2 = p.getAge(); String name2 = p.getName(); if(age2 == age && name.equals(name2)){ return true; } //出现任何一个成员变量不同,都不能称为相同的对象. return false; } */ } public class Demo5 { public static void main(String[] args) { ArrayList list = new ArrayList(); // 创建自定义对象 Person p1 = new Person("tom",15); Person p2 = new Person("toms",16); list.add(p1); list.add(p2); //创建新集合 ArrayList list2 = new ArrayList(); for (Object obj : list) { if(!list2.contains(obj)){//底层调用的是equals方法.根据返回值判断是否能添加成功 list2.add(obj); } } for (Object object : list2) { Person p = (Person)object; System.out.println(p.getName() +"--"+ p.getAge()); } } }
note:技巧
1.5 contains方法
思路:创建新集合,从原集合里拿出元素放入新集合,放入的同时做判断
使用的是contains方法
通过查看contains方法的源码,实际上调用的是要添加元素的equals方法
即:如果要添加元素对已经存在的元素调用equals方法,返回true表明已经存在,返回false表明不存在.
默认equals是继承自Object类的,只是简单的比较地址
自定义类要重写equals方法,告知虚拟机到底什么情况下对象才是”相等”的。
import java.util.ArrayList; /* *重写equals方法原则 * 1.先进行非空判断 * 2.转换成同类型 * 3.对所有的成员变量进行比较,所有的成员变量都相同的情况下才是相同的对象 * * */ 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; } public Person() { super(); } public Person(String name, int age) { super(); this.name = name; this.age = age; } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } @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方法,告诉虚拟机什么情况下两个对象才是相同的对象 * 步骤:非空判断 --> 类型转换 --> 成员变量比较 */ /* @Override public boolean equals(Object obj) { // return true; //所有的成员变量都相同的情况下,两个对象才是相等的. if(obj == null){ return false; } //把传入的参数进行类型转换,同类才能比 Person p = (Person)obj; int age2 = p.getAge(); String name2 = p.getName(); if(age2 == age && name.equals(name2)){ return true; } //出现任何一个成员变量不同,都不能称为相同的对象. return false; } */ } public class Demo5 { public static void main(String[] args) { ArrayList list = new ArrayList(); // 创建自定义对象 Person p1 = new Person("tom",15); Person p2 = new Person("toms",16); list.add(p1); list.add(p2); //创建新集合 ArrayList list2 = new ArrayList(); for (Object obj : list) { if(!list2.contains(obj)){//底层调用的是equals方法.根据返回值判断是否能添加成功 list2.add(obj); } } for (Object object : list2) { Person p = (Person)object; System.out.println(p.getName() +"--"+ p.getAge()); } } }
1.6 并发修改异常
在使用迭代器和增强for循环遍历ArrayList的时候,使用集合本身的方法修改了集合,将导致并发修改异常:ConcurrentModificationException (两个不要交叉使用)
foreach本质上:是使用了迭代器
1.使用迭代器遍历,使用迭代器删除(修改)元素
2.使用集合本身遍历且非foreach,使用集合本身方法删除(修改)元素
如何添加元素:
查看Iterator接口的方法,没有添加元素的方法
但是它的子接口ListIterator有添加元素的方法
1.7 Vector类
Vector类是1.0就已经有的,在1.2被整合到集合框架中
其中的大部分方法都和ArrayList相同,但它是线程安全的,所以效率要低。
import java.util.Enumeration; import java.util.Vector; /* * * jdk升级的原因: * 1.提供新方法. * 2.简化书写. */ public class VectorDemo { public static void main(String[] args) { Vector v = new Vector<>(); v.addElement("hello"); v.addElement("world"); System.out.println(v.size()); v.removeElement("hello"); System.out.println(v.size()); Enumeration en = v.elements(); while(en.hasMoreElements()){ Object obj = en.nextElement(); System.out.println(obj); } } }
1.8LinkedList类
LinkedList 类底层使用的是链表结构保存数据
LinkedList底层使用的是链表,但是自己维护了一个索引,
所以也提供了get(int index)的方法来通过索引获取元素
但此方法的效率很低,一般不使用。
绝大多数方法和ArrayList相同,只不过多了一些对首尾元素操作的方法
addFirst()
addLast()
remove()
练习:
使用LinkedList类模拟栈结构的集合.
注意是模拟栈结构,不是直接使用LinkedList,即:有一个集合,其中的元素是先进后出.
/* * 练习: 使用LinkedList类模拟栈结构的集合.(FILO,LIFO) 注意是模拟栈结构,不是直接使用LinkedList,即:有一个集合,其中的元素是先进后出. 自己设计一个类: 最基本的方法:存, 取. 在此基础之上体现栈的特点:FILO public class MyStack{ //成员位置包含一个LinkedList LinkedList list = new LinkedList(); //add:真正操作的是list //get:真正操作的是list } */ import java.util.LinkedList; class MyStack{ //在成员位置保持一个LinkedList的引用 LinkedList list = new LinkedList(); //add public void add(Object obj){ list.addFirst(obj); } //get public Object get(){ return list.pop(); } //提供判断是否含有元素方法 public boolean isEmpty(){ return list.isEmpty(); } } public class LinkedListDemo2 { public static void main(String[] args) { MyStack ms = new MyStack(); ms.add("hello"); ms.add("world"); ms.add("java"); ms.add("hadoop"); ms.add("mysql"); // // System.out.println(ms.get()); // System.out.println(ms.get()); // System.out.println(ms.get()); // System.out.println(ms.get()); // System.out.println(ms.get()); // System.out.println(ms.get()); while(!ms.isEmpty()){ System.out.println(ms.get()); } } }