List集合以及集合泛型


List集合

List集合的子实现类的特点:

ArrayList:
底层数据结构是数组的形式,满足数组结构的特点:查询快,增删慢
从线程安全问题来看:线程不安全的,不同步,执行效率高,由于ArrayList是List集合的子实现类,它元素可以重复,并且存储和取出一致

import java.util.ArrayList;
import java.util.Iterator;

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);
		}
	}
}

遍历自定义对象
import java.util.ArrayList;
import java.util.Iterator;

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);
		}
	}
}


练习:


需求:ArrayList去除集合中字符串的重复元素
两种方法:
  1)创建一个新集合,把没有重复的字符串存进去,并遍历
 
  2)由选择排序的逻辑想到:
       拿0索引对应的元素依次和后面索引对应的元素进行比较
       同理,1索引对应的元素和后面.....

       前面的索引对应的元素如果和后面索引对应的元素重复了,从集合移出后面索引的对应的元素

import java.util.ArrayList;

public class ArrayListTest2 {

	public static void main(String[] args) {
		
		// 创建一个集合,添加重复元素
		ArrayList<String> array = new  ArrayList<String>();
		

		array.add("hello");
		array.add("hello");
		array.add("Javaweb");
		array.add("world");
		array.add("world");
		array.add("Java");
		array.add("Java");
		array.add("hello");
		array.add("Javaweb");
		array.add("JavaEE");
		array.add("JavaEE");

		ArrayList<String> newArray = new ArrayList<String>();
		
		for(String s1:array) {
			//判断新集合是否包含旧集合中的元素,没有就添加到新集合
			if(!newArray.contains(s1)) {
				newArray.add(s1);
			}
		}
		//遍历新集合
		for(String s2 : newArray) {
			System.out.println(s2);
		}
		
		//System.out.println(array);
		for (int x = 0; x < array.size() - 1; x++) {
			for (int y = x + 1; y < array.size(); y++) {
				//判断是否重复
				if (array.get(x).equals(array.get(y))) {
					array.remove(y);
					y--;
				}
			}
		}		
 //增强for遍历
		for(String s3:array) {
			System.out.println(s3);
		}
	}
}
需求:ArrayList去除集合中自定义对象的重复值(对象的成员变量值都相同)

import java.util.ArrayList;

/**
 * 需求:ArrayList去除集合中自定义对象的重复值(对象的成员变量值都相同)
 * 
 * */
public class ArrayListTest3 {

	public static void main(String[] args) {
		//创建集合
		ArrayList<Student> array = new ArrayList<Student>();
		
		//创建学生对象
		Student s1 = new Student("李白", 23); 
		Student s2 = new Student("虞姬", 25);
		Student s3 = new Student("李白", 23);
		Student s4 = new Student("王昭君", 25);
		Student s5 = new Student("甄姬", 28);
		Student s6 = new Student("甄姬", 28);
		Student s7 = new Student("王昭君", 25);
		Student s8 = new Student("王昭君", 21);
		//给集合添加元素
		array.add(s1);
		array.add(s2);
		array.add(s3);
		array.add(s4);
		array.add(s5);
		array.add(s6);
		array.add(s7);
		array.add(s8);
		//创建一个新集合
		ArrayList<Student> newArray = new ArrayList<Student>();
		for(Student st1 : array) {
			////判断新集合中是否包含这些对象
			if(!newArray.contains(st1)) {
				newArray.add(st1);
			}
		}
		//遍历新集合
		for(Student st2 :newArray) {
			System.out.println(st2);
		}
		
/**
 * 发现重复元素依然存在,为什么呢?
 * contains()底层依赖于一个equals()方法,equals()方法是Object类的中的方法,该法默认比较的是对象的地址值是否相同,必须要重写Object中的eqauls()
 *  方法,才能比较内容是否相同;
 *  		在自定义对象的类中重写Object中的equasl()方法,才能比较成员变量的值是否相同
 *  看源码:
 *  
 *  		ArrayList集合的Contains()源码
 *  		  public boolean contains(Object o) {
 *      		return indexOf(o) >= 0;
 *  }
 *
 *
 *   public int indexOf(Object o) {
 *      if (o == null) {
 *           for (int i = 0; i < size; i++)
 *               if (elementData[i]==null)
 *                   return i;
 *       } else {
 *           for (int i = 0; i < size; i++)
 *               if (o.equals(elementData[i]))
 *                   return i;
 *       }
 *       return -1;
 *   }
 *  重写equasl()方法后,重复元素删除成功
 */

		
	}
}
练习:集合的嵌套遍历
public class ArrayListTest {

	public static void main(String[] args) {
		//创建班级集合
		ArrayList<ArrayList<Student>> bigArray = new ArrayList<ArrayList<Student>>();
		//创建第一个学生集合
		ArrayList<Student> firstArray = new ArrayList<Student>();
		//创建学生对象
		Student s1 = new Student("孙尚香", 18);
		Student s2 = new Student("刘备", 23);
		Student s3 = new Student("至尊宝", 27);
		Student s4 = new Student("紫霞仙子", 25);
		
		firstArray.add(s1);
		firstArray.add(s2);
		firstArray.add(s3);
		firstArray.add(s4);
		//将第一个学生集合添加到班级集合
		bigArray.add(firstArray);
		//创建第二个学生集合
		ArrayList<Student> secondArray = new ArrayList<Student>();
		Student s5 = new Student("叶问水", 18);
		Student s6 = new Student("dreamer_96", 21);
		Student s7 = new Student("二狗子", 27);
		secondArray.add(s5);
		secondArray.add(s6);
		secondArray.add(s7);
		bigArray.add(secondArray);
		//增强for遍历
		for(ArrayList<Student> array:bigArray) {
			for(Student s:array) {
				
				System.out.println(s.getName()+"----"+s.getAge());
			}
		}
		
	}
}


Vector:


底层数据结构是数组的形式,查询快,增删慢
从线程角度看:线程安全的类,同步,执行效率低


特有功能:

public void addElement(E obj)------->相当于:add(Object e)

public Enumeration<E> elements()----->相当于:Iterator iterator() ;


Enumeration<E>接口:向量的组件枚举有两个方法
boolean hasMoreElements():------>相当于:hasNext()
Object nextElement():----------->相当于:next();

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);
		}
	}
}	


LinkedList:


底层数据结构是链接列表,特点:查询慢,增删快
从线程角度看:线程不安全的一个类,不同步,执行效率高

如果实现多线程程序,一般要是安全的类:
StringBuffer,Vector<E>,hashtable<K,V>

synchronized(同步锁对象){
代码;
}

特有功能:
添加功能:
public void addFirst(E e)将指定元素插入此列表的开头。
public void addLast(E e)将指定元素添加到此列表的结尾。
获取功能:
public Object getFirst()返回此列表的第一个元素
public Object getLast()返回此列表的最后一个元素。
删除功能:
public Object removeFirst()移除并返回此列表的第一个元素。
public Object removeLast()移除并返回此列表的最后一个元素。



如果在一般的需求中没有指明使用集合去完成,都默认采用ArrayList
如果需求中要考虑线程安全,那么使用Vector集合!


  笔试过程中,一些需求用到集合:就是用ArrayList

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);
	}
}


 
 

关于数据结构

自定义栈集合类,然后使用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);
		}
	}
}

JDK5.0以后的新特性:

泛型,增强for循环,可变参数,静态导入,自动拆装箱,枚举等等

一.泛型

泛型的引出:
当使用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)获取数据的时候,不用强制类型转换了

注意:给类上加入了泛型,在实际测试中,给定了数据类型,获取数据的时候就必须应该类型来接收,否则不匹配
public class GenericDome {

	public static void main(String[] args) {
		//创建ArrayList集合
		ArrayList<Student> array = new ArrayList<Student>();
		Student s1 = new Student("李白",24);
		Student s2 = new Student("杜甫",21);
		Student s3 = new Student("白居易",28);
		Student s4 = new Student("汪伦",25);
		//给集合添加元素
		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());
		}
	}
}

泛型定义在方法上:
public class ObjectTool{
	
	//将泛型定义在方法上
	public <T> void show(T t){
		System.out.println(t);
	}
}

泛型可以提供程序的安全性!
   早期的时候,用Object类型代表任意的类型
   向上转型是不会出现问题的,但是向下转型的时候,由于隐藏了类型转换,导致出现错误!

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);
	}
}	


二.增强for循环:

书写格式:
   for(集合或者数组中的数据类型 变量名:集合或者数组的对象名){
   输出变量名;
   }
  
  增强for循环的弊端:
遍历数组或者集合的时候,数组对象或者集合对象不能为null
   如果对象为空,一般加上非空判断
  
  增强for循环的出现就是为了替代迭代器遍历集合的,以后开发中就是用增强for遍历元素
public class ForDome {

	@SuppressWarnings("unused")
	public static void main(String[] args) {
		//定义一个数组,静态初始化
		int []  arr = {12,13,34,5,22};
		//之前for循环遍历
		for(int x = 0;x < arr.length;x++) {
			System.out.print(arr[x]+" ");//12 13 34 5 22 
		}
		System.out.println();
		//增强for遍历
		for(int i:arr) {
			System.out.print(i+" ");//12 13 34 5 22
		}
		System.out.println();
		//字符串
		String [] strArray = {"一杯敬故乡","一杯敬远方"};
		//增强for遍历
		for(String s:strArray) {
			System.out.print(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()) {
			System.out.print(it.next()+" ");// hello world java 
		}
		//增强for遍历
		/*for(String s:array) {
			System.out.print(s+" ");//hello world java 
			
			if("world".equals(s)) {//java.util.ConcurrentModificationException
				array.add("Javaweb");
			}
		}*/
		array = null;
		if(array != null) {//非空判断
			for(String s:array) {
			
				System.out.print(s+" "); //java.lang.NullPointerException空指针异常 增强for弊端
			}
		}
		
	}
}


猜你喜欢

转载自blog.csdn.net/dreamer_96/article/details/78509309