一.List集合的子实现类特点
1.ArrayList:
底层数据结构是数组的形式,满足数组结构的特点:查询快,增删慢
从线程安全问题来看:线程是不安全的,不同步,执行效率高。
2.Vector:
底层数据结构是数组的形式,查询快,增删慢。
从线程安全角度看:线程安全的一个类,同步,执行效率低
3.LinkedList:
底层数据结构是链接列表,特点:查询慢,增删快
从线程角度考虑:线程不安全,不同步,执行效率高
注意:实现多线程程序:一般要是安全的类:StringBuffer、Vector、hashtable<K、V>
如果在一般的需求中没有指明使用哪个集合去完成,都默认采用ArrayList,如果需求考虑到线程安全,需要用Vector.
二.集合存储字符串和自定义对象的特点
1.ArrayList:元素可以重复,并且存储和取出一致
1)存储字符串遍历
package day_14_11_11.ArryList;
import java.util.ArrayList;
import java.util.Iterator;
public class ArrayListDemo {
public static void main(String[] args) {
// 创建ArrayList集合对象
ArrayList <String> array = new ArrayList<String>();
//给集合添加元素
array.add("want");
array.add("travel");
array.add("have");
array.add("money");
//遍历集合元素
//获取迭代器对象
Iterator<String> it = array.iterator();
while(it.hasNext()){
System.out.print(it.next()+" "); //want travel have money
}
}
}
2)存储自定义对象
注意:自定义类重写toString方法
package day_14_11_11.ArryList;
import java.util.ArrayList;
import java.util.Iterator;
/**
* ArrayList集合来存储自定义对象并遍历
* */
public class ArrayListDemo2 {
public static void main(String[] args) {
// 创建ArrayList集合对象
ArrayList<Student> arry = new ArrayList<Student>();
//创建Student对象
Student s1 = new Student("zhang",12);
Student s2 = new Student("san",13);
Student s3 = new Student("li",14);
Student s4 = new Student("si",15);
//给集合添加元素
arry.add(s1);
arry.add(s2);
arry.add(s3);
arry.add(s4);
//获取迭代器对象
Iterator<Student> it = arry.iterator();
//遍历集合
while(it.hasNext()){
Student s = (Student)it.next();
System.out.println(s); //如果Student不重写toString,就会输出全路径名称@地址值
}
}
}
2.Vector
1)添加功能:public void addElement(E Obj)
2)获取接口:public Enumeration<E> elements()
Enumeration<E>接口:向量的组件枚举有两个方法
boolean hasMoreElements():
Object nextElement():
package day_14_11_11.Vector;
import java.util.Enumeration;
import java.util.Vector;
public class VectorDemo {
public static void main(String[] args) {
// 创建Vector集合对象
Vector<String> v = new Vector<String>();
//添加元素
//public void addElemet(E obj)
v.addElement("want");
v.addElement("travel");
v.addElement("have");
v.addElement("money");
//public Enumeration<E> elements()
Enumeration<String> en = v.elements();
//遍历元素
while(en.hasMoreElements()){
//获取元素
System.out.print(en.nextElement()+" ");
}
}
}
3.LinkedList:存储和取出不一样
1)添加功能:
public void addFirst(E e)将指定的元素插入此列表的开头
public void addLast(E e)将指定的元素添加到此列表的结尾
2)获取功能:
public Object getFirst()返回此列表的第一个元素
public Object getLast()返回此列表的最后一个元素
3)删除功能:
public Object removeFirst()移除并返回此列表的第一个元素
public Object removeLast()移除并返回此列表的第一个元素
package day_14_11_11;
import java.util.LinkedList;
public class LinkedDemo {
public static void main(String[] args) {
// 创建LinkedList集合对象
LinkedList<String> link = new LinkedList<String>();
//添加元素
link.addFirst("you");
link.addFirst("want");
link.addFirst("you");
link.addFirst("can");
//1.public void addFirst(E e)将指定元素插入此列表的开头
link.addFirst("JavaWeb"); //[JavaWeb, can, you, want, you]
//public void addLast(E e)将指定元素添加到此列表的结尾。
link.addLast("over"); //[JavaWeb, can, you, want, you, over]
//2.public Object getFirst()返回此列表的第一个元素
System.out.println(link.getFirst()); //JavaWeb
//public Object getLast()返回此列表的最后一个元素。
System.out.println(link.getLast()); //over
//3.public Object getFirst()返回此列表的第一个元素
System.out.println(link.removeFirst()); //JavaWeb
//public Object getLast()返回此列表的最后一个元素。
System.out.println(link.removeLast()); //over
System.out.println(link);
}
}
练习:ArrayList去除集合中字符串的重复元素,两种解决方法
方法一:1.用选择排序的思想,用第一个元素和后面元素一次比较;
2.若两个元素的值相等(用equals()),则删除重复的元素;
3.再重新遍历输出
public class ArrayListTest {
public static void main(String[] args) {
//创建ArrayList集合对象
ArrayList arry = new ArrayList();
//给集合添加元素
arry.add("hello");
arry.add("balala");
arry.add("hello");
arry.add("travel");
arry.add("travel");
//用选择排序的思想
for(int i=0;i<arry.size()-1;i++){
for(int j=i+1;j<arry.size();j++){
if(arry.get(i)==arry.get(j)){
arry.remove(j);
j--;
}
}
}
//获取迭代器
Iterator it = arry.iterator();
while(it.hasNext()){
String s = (String)it.next();
System.out.println(s);
}
}
}
方法二:创建一个新的集合
package day_14_11_11.ArryList;
import java.util.ArrayList;
import java.util.Iterator;
/**
* 需求:ArrayList去除集合中字符串的重复元素
* 1)首先创建一个集合
* 2)给集合中添加很多重复元素
* 3)再次创建一个新集合
* 4)获取迭代器遍历
* 5)获取到该集合中的每一个元素
* 判断新集合中是否包含这些有素
* 有,不搭理它
* 没有.说明不重复,添加进来
* 6)遍历新集合
*/
public class ArrayListTest {
public static void main(String[] args) {
//1)创建一个集合
ArrayList<String> array = new ArrayList<String>() ;
//2)给集合中添加多个重复元素
array.add("hello");
array.add("balala");
array.add("hello");
array.add("travel");
array.add("travel");
//3)创建一个新的集合
ArrayList<String> newArray = new ArrayList<String>() ;
//4)遍历旧集合,获取当前迭代器对象
Iterator<String> it = array.iterator() ;
while(it.hasNext()){
String s = it.next() ;
//拿到了每一个字符串元素
//判断新集合是否包含旧集合中的元素
if(!newArray.contains(s)){
//不包含,就将元素直接添加到新集合中
newArray.add(s) ;
}
}
//遍历新集合
Iterator<String> it2 = newArray.iterator() ;
while(it2.hasNext()){
String s = it2.next() ;
System.out.println(s);
}
}
}
练习:ArrayList去除自定义对象中的重复值
注意:自定义对象的类中必须重写equals()方法;否则不能去除自定义对象的重复值,因为contains()底层依赖于一个equals()方法,equals()方法是Object类的中的方法,该法默认比较的是对象的地址值是否相同,必须要重写Object中的eqauls() 方法,才能比较内容是否相同;
package day_14_11_11.ArryList;
import java.util.ArrayList;
import java.util.Iterator;
public class ArrayListTest2 {
public static void main(String[] args) {
//创建一个ArrayList集合对象
ArrayList<Student> array = new ArrayList<Student>() ;
//2)创建学生对象
Student s1 = new Student("高圆圆", 27) ;
Student s2 = new Student("高圆圆", 20) ;
Student s3 = new Student("邓超", 29) ;
Student s4 = new Student("邓超", 25) ;
Student s5 = new Student("黄晓明", 30) ;
Student s6 = new Student("高圆圆", 27) ;
//将学生对象添加到array集合中
array.add(s1) ;
array.add(s2) ;
array.add(s3) ;
array.add(s4) ;
array.add(s5) ;
array.add(s6) ;
//3)创建一个新集合
ArrayList<Student> newArray = new ArrayList<Student>() ;
//遍历旧集合,获取迭代器对象
Iterator<Student> it = array.iterator() ;
while(it.hasNext()){
Student s = it.next() ;
//判断新集合中是否包含这些对象
if(!newArray.contains(s)){
//不包含的对象才能添加新集合
newArray.add(s) ;
}
}
//遍历新集合
Iterator<Student> it2 = newArray.iterator() ;
while(it2.hasNext()){
Student s = it2.next() ;
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
package day_14_11_11.ArryList;
public class Student {
private String name;
private int age;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = 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 "Student [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;
Student other = (Student) 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;
}
}
练习:使用LinkedList模拟一个栈结构的特点
package day_14_11_11;
import java.util.Iterator;
import java.util.LinkedList;
//需求:使用LinkedList模拟一个栈结构的特点
public class LinkedListDemo {
public static void main(String[] args) {
//创建LinkedList集合的对象
LinkedList<String> link = new LinkedList<String>() ;
//LinkedList集合的特有功能:addFirst(Object e)
//栈结构的特点:先进后出
link.addFirst("travel") ;
link.addFirst("need") ;
link.addFirst("money") ;
Iterator<String> it = link.iterator() ;
while(it.hasNext()){
String s = it.next() ;
System.out.println(s);
}
}
}
练习:自定义栈集合类并进行测试
package day_14_11_11.stack;
import java.util.LinkedList;
public class MyStack {
//成员变量
private LinkedList link ;
//无参构造
//通过无参进行LinkedList集合对象 的创建
public MyStack(){
link = new LinkedList() ;
}
//添加功能
public void add(Object obj){
link.addFirst(obj) ;//向集合中列表插入到第一个元素
}
//获取功能
public Object get(){
return link.removeFirst() ;//删除集合列表中的第一个元素,返回值是被删除的元素
}
//定义判断集合是否为空
public boolean isEmpty(){
return link.isEmpty() ;
}
}
package day_14_11_11.stack;
public class MystackTest {
public static void main(String[] args) {
//创建自定义栈集合类的对象
MyStack ms = new MyStack() ;
//调用添加功能
ms.add("travel") ;//link.addFier("travel")
ms.add("have") ;
ms.add("money") ;
//当前栈集合中有元素了
/*//获取集合集合中的元素
System.out.println(ms.get());
System.out.println(ms.get());
System.out.println(ms.get());
//java.util.NoSuchElementException:没有这样元素的异常
System.out.println(ms.get());*/
//给当前集合对象来判断:判断集合是否为空
while(!ms.isEmpty()){
System.out.println(ms.get());
}
}
}
三.泛型
1.定义:把数据类型的明确工作提供提前到了创建对象或者是调用方法的时期明确的一种特殊类型.参数化类型,可以像参数一样进行传递
格式:<引用类型>:泛型只能放引用类型
2.好处:1)将运行时期异常提前到了编译时期
2)解决了黄色警告线问题
3)获取数据的时候,不用强制类型转换了
3.应用:一般情况:泛型可以应用在接口,类,或者方法上;主要用在集合中比较多!
3.应用:一般情况:泛型可以应用在接口,类,或者方法上;主要用在集合中比较多!
jdk7特性:泛型推断!建议:后面永远给出类型
练习:使用三种方式遍历集合
package genetic;
import java.util.ArrayList;
//import java.util.Iterator;
public class GeneticDemo1 {
/**
* @param args
*/
public static void main(String[] args) {
// 创建集合对象
ArrayList<Student> arry = new ArrayList<>();
//创建学生对象
Student s1 = new Student("zhang",13);
Student s2 = new Student("san",14);
Student s3 = new Student("li",15);
Student s4 = new Student("si",16);
//给集合添加元素
arry.add(s1);
arry.add(s2);
arry.add(s3);
arry.add(s4);
/*//1.获取迭代器对象
Iterator<Student> it = arry.iterator();
//遍历
while(it.hasNext()){
Student s = it.next();
System.out.println(s.getName()+"-----"+s.getAge());
}*/
/*2.//使用toArray遍历,返回的是Object类型,所以要重写toString方法获取对象中的值
Object[] objs = arry.toArray();
for(int i=0;i<objs.length;i++){
System.out.println(objs[i].toString());
}*/
//3.增强for循环:for(集合或者数组中的数据类型 变量名 : 集合或数组的对象名)
for(Student s : arry){
System.out.println(s.getName()+"----"+s.getAge());
}
}
}
package genetic;
public class Student {
private String name;
private int age;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(String name, int age) {
super();
this.name = name;
this.age = 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 "Student [name=" + name + ", age=" + age + "]";
}
}
1).将泛型定义在类上:
package day_14_11_11.genericity;
public class ObjectTool <T>{
private T obj;
//获取
public T getObj(){
return obj;
}
//设置
public void setObj(T obj){
this.obj = obj;
}
}
package day_14_11_11.genericity;
public class ObjectToolDemo {
public static void main(String[] args) {
// 创建ObjectTool<T>对象
ObjectTool<String> ot = new ObjectTool<String>() ;
//设置数据
ot.setObj("han");
//获取数据
//Integer i = ot.getObj(); //编译不能通过,因为给类加上了泛型
String name = ot.getObj();
System.out.println("姓名是:"+name);
//创建对象
ObjectTool<Integer> ot2 = new ObjectTool<Integer>() ;
//设置数据
ot2.setObj(27) ;
//获取数据
//String s = ot2.getObj(); //编译不能通过,因为给类加上了泛型
Integer age = ot2.getObj();
System.out.println("年龄是"+age);
}
}
2)将泛型定义在方法上
package day_14_11_11.genericity;
public class ObjectTool2 {
public <T> void show(T t){
System.out.println(t);
}
}
package day_14_11_11.genericity;
public class ObjectToolDemo2 {
public static void main(String[] args) {
// 创建工具类对象
ObjectTool2 ot = new ObjectTool2();
ot.show("hello");
ot.show(true);
ot.show(100);
}
}
3)j将泛型定义在接口上
package day_14_11_11.genericity;
public interface Inter<T> {
public abstract void show(T t);
}
package day_14_11_11.genericity;
//接口加入了泛型:
/**
* 情况一:接口的子实现类已经知道传递的是什么数据类型
* public class InterImpl<String> implements Inter<String>
* */
public class InterImpl<Boolean> implements Inter<Boolean>{
@Override
public void show(Boolean b) {
// TODO Auto-generated method stub
System.out.println(b);
}
}
/**
* 情况二:接口的子实现类在实现接口的时候,不知道具体的数据类型是什么,在测试类的时候,传入具体数据类型
* */
/*public class InterImpl<T> implements Inter<T> {
@Override
public void show(T t) {
System.out.println(t);
}
}
*/
package day_14_11_11.genericity;
public class InterDemo {
public static void main(String[] args) {
// 创建接口对象
//第一种情况的测试
Inter<Boolean> b = new InterImpl<Boolean>();
b.show(true);
//第二种情况的测试
Inter<Integer> i = new InterImpl<Integer>();
i.show(18);
Inter<String> i2 = new InterImpl<String>();
i2.show("韩庚");
}
}
四.泛型的高级:通配符
1.<?> :可以是任意类型,包括Object类型以及任意的Java类
2.<? extends E>:向下限定,E类型以及E类型的子类
3.<? super E>:向上限定,E类型以及E类型的父类
package day_14_11_11.genericity;
import java.util.ArrayList;
import java.util.Collection;
/**
* 泛型的高级:通配符
* <?> :可以是任意类型,包括Object类型以及任意的Java类
* <? extends E>:向下限定,E类型以及E类型的子类
* <? super E>:向上限定,E类型以及E类型的父类
*/
public class GenericDemo {
public static void main(String[] args) {
// 创建Collection集合的对象
//最起码:前后的数据类型保持一致
//Collection<Object> c1 = new ArrayList<Animal>() ;
//Collection<Object> c2 = new ArrayList<Cat>() ;
//Collection<Object> c3 = new ArrayList<Dog>() ;
Collection<Object> c3 = new ArrayList<Object>() ;
// <?> :可以是任意类型,包括Object类型以及任意的Java类
Collection<?> c4 = new ArrayList<Object>() ;
Collection<?> c5 = new ArrayList<Animal>() ;
Collection<?> c6 = new ArrayList<Cat>() ;
Collection<?> c7 = new ArrayList<Dog>() ;
//<? extends E>:向下限定,E类型以及E类型的子类
Collection<? extends Object> c8 = new ArrayList<Object>() ;
Collection<? extends Animal> c9 = new ArrayList<Animal>() ;
//Collection<? extends Animal> c10 = new ArrayList<Object>() ;
Collection<? extends Object> c11 = new ArrayList<Cat>() ;
//<? super E>:向上限定,E类型以及E类型的父类
Collection<? super Animal> c12 = new ArrayList<Object>() ;
Collection<? super Animal> c13 = new ArrayList<Animal>() ;
//Collection<? super Animal> c14 = new ArrayList<Dog>() ;
}
}
//自定义两个类
class Animal{
}
class Cat extends Animal{
}
class Dog extends Animal{
}
五.增强for
1.书写格式:
for(集合或者数组中的数据类型 变量名:集合或者数组的对象名){
输出变量名;
}
2.for循环的弊端
遍历数组或者集合的时候,数组对象或者集合对象不能为null
如果对象为空,一般要加上非空判断
注意:for循环的出现是为了替代迭代器遍历集合的,在以后的开发中用增强for遍历元素
package day_14_11_11.forpack;
import java.util.ArrayList;
public class ForDemo {
public static void main(String[] args) {
// 定义一个字符串数组,并遍历
String[] strArray = {"travel","need","money"};
//增强for遍历
for(String s : strArray){
System.out.print(s+" ");
}
创建ArrayList集合对象,添加并遍历元素
ArrayList<String> array = new ArrayList<String>() ;
//添加元素
array.add("travel") ;
array.add("need") ;
array.add("money") ;
//增强for遍历集合
for(String s : array){
//判断当前集合是否有"need",如果有添加play
if("need".equals(s)){
//使用集合添加元素,会报java.util.ConcurrentModificationException
array.add("play");
}
}
System.out.println("---------");
}
}