一 List集合的子实现类的特点:
1 ArrayList:
底层数据结构是数组的形式,满足数组结构的特点:查询快,增删慢
从线程安全问题来看:线程不安全的,不同步,执行效率高
2 Vector:
底层数据结构是数组的形式,查询快,增删慢
从线程角度看:线程安全的类,同步,执行效率低
3 LinkedList:
底层数据结构是链接列,特点:查询慢,增删快
从线程角度看:线程不安全的一个类,不同步,执行效率高
如果实现多线程程序,一般要是安全的类:
StringBuffer,Vector<E>,hashtable<K,V>
synchronized(同步锁对象){
代码;
}
如果在一般的需求中没有指明使用集合去完成,都默认采用ArrayList
如果需求中要考虑线程安全,那么使用Vector集合!
笔试过程中,一些需求用到集合:就是用ArrayList
二ArrayList:
底层数据结构是数组的形式,满足数组结构的特点:查询快,增删慢
从线程安全问题来看:线程不安全的,不同步,执行效率高
由于ArrayList是List集合的自实现类,它元素可以重复,并且存储和取出一致
存储字符串并遍历
public class ArrayListDemo {
public static void main(String[] args) {
//创建一个ArrayList集合对象
ArrayList array = new ArrayList() ;
//添加元素
array.add("hello") ;
array.add("hello") ;
array.add("world") ;
array.add("world") ;
array.add("java") ;
array.add("java") ;
//遍历元素:
//1)获取迭代器对象
Iterator it = array.iterator() ;
while(it.hasNext()){
String s = (String)it.next() ;
System.out.println(s);
}
}
}
ArrayList集合来存储自定义对象并遍历
public class ArrayListDemo2 {
public static void main(String[] args) {
//创建ArrayList集合对象
ArrayList array = new ArrayList() ;
//创建几个学生对象
Student s1 = new Student("高圆圆", 27) ;
Student s2 = new Student("唐嫣", 25) ;
Student s3 = new Student("邓超", 29) ;
Student s4 = new Student("黄晓明", 28) ;
//给集合添加元素
array.add(s1) ;
array.add(s2) ;
array.add(s3) ;
array.add(s4) ;
//获取迭代器并遍历
Iterator it = array.iterator() ;
while(it.hasNext()){
//java.lang.ClassCastException: org.westos_01.Student cannot be cast to java.lang.String
// String s = (String)it.next() ;
Student s = (Student) it.next() ;
System.out.println(s);
}
}
}
import java.util.Enumeration;
import java.util.Vector;
2 Vector:
底层数据结构是数组的形式,查询快,增删慢
从线程角度看:线程安全的类,同步,执行效率低
特有功能:
publicvoid addElement(E obj)------->相当于:add(Object e)
publicEnumeration<E> elements()----->相当于:Iteratoriterator() ;
Enumeration<E>接口:向量的组件枚举有两个方法
booleanhasMoreElements():------>相当于:hasNext()
ObjectnextElement():----------->相当于:next();
源码:
synchronized:同步锁(多线程中讲):它就可以保证线程安全!
public synchronized void addElement(E obj) {//由同步代码块演变过来的同步方法
modCount++;
ensureCapacityHelper(elementCount+ 1);
elementData[elementCount++]= obj;
}
public class VectorDemo {
public static void main(String[] args) {
//创建一个Vector集合对象
Vector v = new Vector() ;
//添加元素
//public void addElement(E obj)
v.addElement("hello")
v.addElement("hello");
v.addElement("world");
v.addElement("Java");
//public Enumeration<E> elements()----->相当于:Iterator iterator() ;
Enumeration en = v.elements() ;
//遍历元素
boolean hasMoreElements():------>相当于:hasNext()
Object nextElement():----------->相当于:next();
while(en.hasMoreElements()){
//获取元素
String s = (String)en.nextElement() ;
System.out.println(s);
}
}
} .
3 LinkedList:
底层数据结构是链接列表,特点:查询慢,增删快
从线程角度看:线程不安全的一个类,不同步,执行效率高
特有功能:
添加功能:
publicvoid addFirst(E e)将指定元素插入此列表的开头。
publicvoid addLast(E e)将指定元素添加到此列表的结尾。
获取功能:
publicObject getFirst()返回此列表的第一个元素
publicObject getLast()返回此列表的最后一个元素。
删除功能:
publicObject removeFirst()移除并返回此列表的第一个元素。
publicObject removeLast()移除并返回此列表的最后一个元素。
public class LinkedListDemo {
public static void main(String[] args) {
//创建LinkedList集合
LinkedList link = new LinkedList() ;
//添加元素
link.addFirst("hello") ;
link.addFirst("world") ;
link.addFirst("Java") ;
//public void addFirst(E e)将指定元素插入此列表的开头
/*link.addFirst("android") ;
link.addLast("JavaWeb") ;*/
/**
* public Object getFirst()返回此列表的第一个元素
public Object getLast()返回此列表的最后一个元素。
*/
/*
Object obj = link.getFirst() ;
System.out.println(obj);
Object obj2 = link.getLast() ;
System.out.println(obj2);*/
/**
* public Object removeFirst()移除并返回此列表的第一个元素。
public Object removeLast()移除并返回此列表的最后一个元素。
*/
/*System.out.println("removeFirst:"+link.removeFirst());
System.out.println("removeLast:"+link.removeLast());*/
//输出集合
System.out.println("link:"+link);
}
}
4
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 array = new ArrayList() ;
//2)给集合中添加多个重复元素
array.add("hello") ;
array.add("hello") ;
array.add("hello") ;
array.add("world") ;
array.add("world") ;
array.add("world") ;
array.add("Java") ;
array.add("Java") ;
array.add("hello") ;
array.add("Javaweb") ;
array.add("JavaEE") ;
array.add("JavaEE") ;
//3)创建一个新的集合
ArrayList newArray = new ArrayList() ;
//4)遍历旧集合,获取当前迭代器对象
Iterator it = array.iterator() ;
while(it.hasNext()){
String s = (String) it.next()
//拿到了每一个字符串元素
//判断新集合是否包含旧集合中的元素
if(!newArray.contains(s)){
//不包含,就将元素直接添加到新集合中
newArray.add(s) ;
}
}
//遍历新集合
Iterator it2 = newArray.iterator() ;
while(it2.hasNext()){
String s = (String) it2.next() ;
System.out.println(s);
}
}
}
由选择排序的逻辑想到:
拿0索引对应的元素依次和后面索引对应的元素进行比较
同理,1索引对应的元素和后面.....
前面的索引对应的元素如果和后面索引对应的元素重复了,从集合移出后面索引的对应的元素
for(intx = 0 ;x <array.size() -1 ; x ++){
for(inty= x +1 ; y <array.size() ;y++){
//判断
if(array.get(x).equals(array.get(y))){
array.remove(y);
y-- ;
}
}
}
//遍历集合
Iteratorit = array.iterator() ;
while(it.hasNext()){
Strings = (String) it.next() ;
System.out.println(s);
}
}
}
//需求:使用LinkedList模拟一个栈结构的特点
//表达的意思:自定义栈集合类,然后使用LinkedList的一些特有功能模拟栈结构特点
public class LinkedListDemo {
public static void main(String[] args) {
//创建LinkedList集合的对象
LinkedList link = new LinkedList() ;
//LinkedList集合的特有功能:addFirst(Object e)
//栈结构的特点:先进后出
link.addFirst("hello") ;
link.addFirst("world") ;
link.addFirst("java") ;
Iterator it = link.iterator() ;
while(it.hasNext()){
String s = (String)it.next() ;
System.out.println(s);
}
}
}
自定义的栈集合类
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() ;
}
}
二泛型
使用ArrayList存储元素给ArrayList集合存储了一些元素,String类型的元素,Integer类型的元素但是通过迭代器遍历元素,由于,系统不知道集合中存储了哪些元素,所有使用String类型接收,就会出现ClassCastException:类转换异常
定义一个数组:字符串数组
// String[]str = new String[3] ;
// str[0]= "hello" ;
// str[1]= "world" ;
// str[2]= 100 ;
数组设计这样好处:提前告诉了开发者,这里只能装String类型的元素,Java根据数组特点---->引出:泛型
泛型:把数据类型的明确工作提供提前到了创建对象或者是调用方法的时期明确的一种特殊类型.参数化类型,可以像参数一样进行传递
格式:
<引用类型>:泛型只能放引用类型
泛型好处:
1)将运行时期异常提前到了编译时期
2)解决了黄色警告线问题
3)获取数据的时候,不用强制类型转换了
import java.util.ArrayList;
import java.util.Iterator;
public class GenericDemo {
public static void main(String[] args) {
//创建ArrayList集合对象
ArrayList array = new ArrayList() ;
//添加元素
array.add("hello") ;
array.add("world") ;
array.add("Java");
// array.add(new Integer(100)) ;
// array.add(10) ;
//相当于:array.add(Integer.valueOf(10)) ;
//遍历集合中的元素,获取迭代器对象
/*Iterator it = array.iterator() ;
while(it.hasNext()){
//java.lang.ClassCastException: java.lang.Integer cannot be cast to java.lang.String
String s = (String) it.next() ;
System.out.println(s);
}*/
2 泛型的应用:
一般情况:泛型可以应用在接口,类,或者方法上;主要用在集合中比较多!
public class GenericDemo2 {
public static void main(String[] args) {
//创建一个ArrayList集合对象
ArrayList<String> array = new ArrayList<String>() ;//jdk7特性:泛型推断!:建议:后面永远给出类型
//给集合中添加元素
array.add("hello") ;
array.add("world") ;
array.add("java") ;
// array.add(10) ;
//获取迭代器对象并遍历
Iterator<String> it = array.iterator() ;
//遍历
while(it.hasNext()){
//不用强制类型转换了
String s = it.next() ;
System.out.println(s);
}
}
}
使用ArrayList集合存储自定义对象并遍历
public class GenericDemo3 {
public static void main(String[] args) {
//创建一个ArrayList集合对象
ArrayList<Student> array = new ArrayList<Student>() ;
//创建学生对象
Student s1 = new Student("RNG",666) ;
Student s2 = new Student("EDG",233 ;
Student s3 = new Student("LGD", 292) ;
Student s4 = new Student("WE", 886) ;
//添加元素
array.add(s1) ;
array.add(s2) ;
array.add(s3) ;
array.add(s4) ;
//获取迭代器
Iterator<Student> it = array.iterator() ;
while(it.hasNext()){
Student s = it.next() ;
System.out.println(s.getName()+"---"+s.getAge());
}
}
}
泛型可以提供程序的安全性
早期的时候,用Object类型代表任意的类型
向上转型是不会出现问题的,但是向下转型的时候,由于隐藏了类型转换,导致出现错误
JDK5以后,提供了泛型可以解决程序的安全性
public class ObjectToolDemo {
public static void main(String[] args) {
//创建ObjectTool对象
ObjectTool ot = new ObjectTool() ;
//设置数据
ot.setObj(27) ;//Object obj = new Integer(27):向上转型
//获取
Integer i = (Integer) ot.getObj() ;//向下转型
System.out.println("年龄是:"+i);
ObjectTool ot2 = new ObjectTool() ;
//设置
ot2.setObj("高圆圆") ;//Object obj = new String("高圆圆") ;
//获取
String str = (String) ot2.getObj() ;//类型转换了:向下转型:隐藏了类型转换
System.out.println("姓名是:"+str);
System.out.println("-------------------------------");
ObjectTool ot3 = new ObjectTool() ;
ot3.setObj("邓超") ;
//java.lang.ClassCastException
Integer ii = (Integer) ot3.getObj() ;//强制类型转换的接收类型不匹配:程序不安全
System.out.println("姓名是:"+ii);
}
}
3工具类
使用泛型:将泛型定义在类上:解决刚才可能出现错误
实际开发中根据具体类型在测试中书写
public class ObjectTool<T> {
private T obj;
//获取
public T getObj(){
return obj ;
}
//设置
public void setObj(T obj){
this.obj = obj ;
}
}
//测试类
public class ObjectToolDemo {
public static void main(String[] args) {
//创建ObjectTool<T>对象
ObjectTool<String> ot = new ObjectTool<String>() ;
//设置数据
ot.setObj("高圆圆") ;
//获取数据
//编译都通过不了
// 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 i = ot2.getObj() ;
System.out.println("年龄是:"+i);
}
}
4 将泛型定义在类型 方法上 接口上
//在工具类中定义几个成员方法
/*public class ObjectTool<T> {
//形式参数是String
public void show(String s){
System.out.println(s);
}
//形式参数是Integer类型
public void show(Integer i){
System.out.println(i);
}
public void show(Boolean b){
System.out.println(b);
}
public void show(T t){
System.out.println(t);
}
}*/
public class ObjectTool{
//将泛型定义在方法上
public <T> void show(T t){
System.out.println(t);
}
}
/把泛型定义在接口上
public interface Inter<T> {
public abstract void show(T t) ;
}
//测试类
public class InterDemo {
public static void main(String[] args) {
//创建接口对象
//第一种情况的测试
Inter<String> i = new InterImpl<String>() ;
i.show("hello") ;
System.out.println("-----------------------------");
//第二种情况:
Inter<Integer> i2 = new InterImpl<Integer>() ;
i2.show(27) ;
Inter<String> i3 = new InterImpl<String>() ;
i3.show("高圆圆") ;
}
}
//接口加入了泛型:
//第一种情况:接口的子实现类已经知道传递的是什么数据类型
/*public class InterImpl<String> implements Inter<String> {
public void show(String t) {
System.out.println(t);
}
}*/
//第二种情况:接口的子实现类在实现接口的时候,不知道具体的数据类型是什么
//在测试类的时候,传入具体数据类型
//面向接口编程
//JavaEE:Sping框架 :AOP:面向切面编程
public class InterImpl<T> implements Inter<T>{
public void show(T t) {
System.out.println(t);
}
}
6
泛型的高级:通配符
<?> :可以是任意类型,包括Object类型以及任意的Java类
<? extends E>:向下限定,E类型以及E类型的子类
<? super E>:向上限定,E类型以及E类型的父类
import java.util.ArrayList;
import java.util.Collection;
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
1DK5以后提供了很多特性:
泛型,增强for循环,可变参数,静态导入,自动拆装箱,枚举等的呢过
增强for循环
书写格式:
for(集合或者数组中的数据类型 变量名:集合或者数组的对象名){
输出变量名;
}
增强for循环的弊端:
遍历数组或者集合的时候,数组对象或者集合对象不能为null
如果对象为空,一般加上非空判断
增强for循环的出现就是为了替代迭代器遍历集合的,以后开发中就是用增强for遍历元素
import java.util.ArrayList;
import java.util.Iterator;
public class ForDemo {
public static void main(String[] args) {
//定义一个数组,静态初始化
int[] arr = {11,22,33,44,55} ;
//普通for循环的遍历
for(int x = 0 ; x < arr.length ; x ++){
System.out.println(arr[x]);
}
System.out.println("---------------------");
//使用增强for遍历
for(int i :arr){
System.out.println(i);
}
System.out.println("-------------------");
//定义一个字符串数组,并遍历
String[] strArray = {"hello","world","java"};
//直接使用增强for循环
for(String s : strArray){
System.out.println(s);
}
System.out.println("-------------------");
//创建ArrayList集合对象,添加并遍历元素
ArrayList<String> array = new ArrayList<String>() ;
//添加元素
array.add("hello") ;
array.add("world") ;
array.add("java") ;
//之前:迭代器遍历
/*Iterator<String> it = array.iterator() ;
while(it.hasNext()){
String s = it.next() ;
//判断当前集合中是否有"world",如果有就添加元素
//java.util.ConcurrentModificationException
if("world".equals(s)){
//使用集合添加元素
array.add("javaee") ;
}
}*/
//使用增强for遍历该集合
for(String s :array){
//获取到每一个元素
//java.util.ConcurrentModificationException
判断当前集合中是否有"world",如果有就添加元素
if("world".equals(s)){
array.add("javaee") ;
}
}
System.out.println("-------------------");
/* array = null ;
//java.lang.NullPointerException:空指针异常
if(array!=null){
//增强for循环
for(String s:array){
System.out.println(s);
}
}*/
}
}
2 使用ArrayList集合存储自定义对象并遍历
1)toArray()
2)Collection集合的迭代器:Iteratoriterator();
3)List集合的迭代器:ListIteratorlistiterator();
4)普通for循环:size()和get(intindex)相结合
5)增强for循环
public class ForDemo2 {
public static void main(String[] args) {
// 创建ArrayList集合
ArrayList<Student> array = new ArrayList<Student>();
// 创建学生对象
Student s1 = new Student("RNG", 27);
Student s2 = new Student("RNG", 20);
Student s3 = new Student("EDG", 29);
Student s4 = new Student("EDG", 25);
// 给集合中添加元素
array.add(s1) ;
array.add(s2) ;
array.add(s3) ;
array.add(s4) ;
//普通for循环:size()和get(int index)相结合
for(int x =0 ; x < array.size() ; x ++){
Student s = array.get(x) ;
System.out.println(s.getName()+"---"+s.getAge());
}
System.out.println("-----------------------");
//Collection集合的迭代器:Iterator iterator();
Iterator<Student> it = array.iterator() ;
while(it.hasNext()){
Student s = it.next() ;
System.out.println(s.getName()+"----"+s.getAge());
}
System.out.println("-----------------------");
//增强for遍历
for(Student s : array){
System.out.println(s.getName()+"----"+s.getAge());
}
}
}