现在的位置: 首页 > 综合 > 正文

java、Collection接口集合和泛型

2018年05月06日 ⁄ 综合 ⁄ 共 7725字 ⁄ 字号 评论关闭

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

1 什么叫集合
  通常情况下,把具有相同性质的一类东西,汇聚成一个整体,就可以称为集合。

2 集合与数组的区别
  从存储的数据类型来看:
可以定义基本类型的数组,用来存储基本类型数据。也可以定义引用类型的数组,存储引用类型的数据;
集合只能存储引用类型,而不能存储基本类型。
  从长度来看:
数组一旦定义后,其长度就不能改变;
集合的长度会自动变化。

3 集合的功能
  集合可以存取元素!这是对容器的基本功能。
  集合还有很多对数据的操作方法,例如查看当前集合中是否包含某个元素、移除指定的元素等功能。

4  集合共性抽取
  无论是什么集合,它们都是集合。所以可以把集合的共性向上抽取,而形成一个体系。在Java集合中的根就是Collection。
当我们学习了Collection的使用,那么就掌握了所有集合的基本操作。(学顶层,用底层)

6  常见的数据结构
         栈、队列、数组、链表
        (1)、后进先出,最上面的元素我们叫栈顶元素!出栈(弹栈),就是把栈顶元素从栈中移除,并返回。压栈,就是把一个新元素放到栈顶位置
        (2)、先进先出,没底的管道。
        (3)、数组的索引速度非常的快,但是添加和删除元素,那么就需要copy数组
        (4)、链表元素在内存中是亲戚关系,链表头元素知道下一个元素的地址,下一个元素又知道下下元素的地址,最后一个元素,即链表尾,它的下一个元素师null。

7  Collection接口
    Collection接口有2个子接口,分别是list接口、Set接口。而他们分别的实现类是:List接口有ArrayList类、Vector类、LinkedList类,Set接口中有HashSet类、TreeSet类。
Collection实例:

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

public class CollectionDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//创建一个Collection接口的实现类ArrayList
		Collection cl = new ArrayList();
		//向集合cl添加元素
		cl.add("Java");
		cl.add("Html");
		cl.add("php");
		//迭代集合cl
		Iterator it = cl.iterator();
		//判断cl集合是否有元素可以迭代
		while (it.hasNext()) {
			//返回下一个迭代的字符串
			String ot = (String) it.next();
			//打印返回的字符
			System.out.println(ot);
		}
	}

}
结果为:Java
      Html
      php

8  ListIterator与Iterator的区别
      ListIterator是Itreator的子接口,它实现了Iterator的所有方法。ListItreator只能为list接口服务。ListItreator有一个特有的功能向前遍历boolean hasPrevious():判断是否前一个元素;Object previous():返回前一个元素;int previousIndex():获取前一个元素的下标。还有一个ListIterator listIterator(int index),返回指定位置的列表迭代器

     ListIterator实例:

import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

public class CollectionDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// 创建一个Collection接口的实现类ArrayList
		List cl = new ArrayList();
		// 向集合cl添加元素
		cl.add("Java");
		cl.add("Html");
		cl.add("php");
		// 迭代集合cl
		ListIterator it = cl.listIterator();
		// 判断cl集合是否有元素可以迭代
		while (it.hasNext()) {
			// 返回下一个迭代的字符串
			String ot = (String) it.next();
		}
		// 逆向遍历,如果有元素就返回true
		while (it.hasPrevious()) {
			// 逆向字符串
			String ot = (String) it.previous();
			// 打印字符串
			System.out.println(ot);
		}
	}

}
结果为:php
      Html
      Java

9  list接口
 list是Collection的子接口!List包子元素存入的顺序!也可以包含重复元素,List可以添加、移除元素,而且List的长度可以改变。

    Lsit接口的特点:
       1.可以添加重复元素。
       2.List集合石有序的
       3.list元素有索引

    ArrayList实例:

import java.util.ArrayList;
import java.util.List;

public class ListDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//创建一个ArrayList集合
		List li = new ArrayList();
		//向集合li添加元素
		li.add("java");
		li.add("mysql");
		li.add("oracle");
		li.add("android");
		li.add("java");
		li.add("java");
		System.out.println(fun(li));
	}
	//定义一个去除list集合中重复元素
	public static List fun(List list) {
		//新建一个newlist集合
		List newlist = new ArrayList();
		//遍历参数集合
		for (Object object : list) {
			//判断新集合是否不包含object
			if (!newlist.contains(object)) {
				//不包含就添加元素
				newlist.add(object);
			}
		}
		//返回新的元素
		return newlist;
	}

}

10  Vector类:
 它是在jdk1.0版本的时候出现的,在1.2版本出现了Iterator迭代器后,它的作用逐渐被替换了。Vector底层用的是数组结构,与ArrayList的作用相同!
  Vector中的方法都是同步的,即Vector是线程安全的。
 
    Vector特有的方法:
         void addElement(Object):等同与add()
         Object elementAt(int):等同与get()
         Object removeElement(Object):等同与remove()
         Enumeration elements():返回枚举器,它是老版本的迭代器!

    Vector对象方法的实例:

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;

public class VectorDemo {

	/**
	 * 适配器模式:
	 * 转换器思想
         * 把Iterator,转换成Enumeration,并返回其方法
	 * 核心,是定义其类型属性。
	 * 
	 */
	public static void main(String[] args) {
		// 创建一个ArrayList集合
		List li = new ArrayList();
		// 添加元素
		li.add("ZhangSan");
		li.add("Lisi");
		li.add("WangWu");
		// 迭代集合
		Iterator it = li.iterator();
		// 创建旧版本迭代对象,并传入it对象
		Enumeration em = new MyTransformer(it);
		prin(em);
	}

	// 封装一个遍历方法,传入参数为接口对象
	public static void prin(Enumeration em) {
		// 判断对象中是否有元素
		while (em.hasMoreElements()) {
			// 返回下一个字符串元素
			String type = (String) em.nextElement();
			// 打印字符串
			System.out.println(type);
		}
	}

}

// 实现Enumeration接口
class MyTransformer implements Enumeration {
	// 定义Iterator类型的属性
	private Iterator it;

	// 在构造器加载的时候创建Iterator对象
	public MyTransformer(Iterator it) {
		this.it = it;
	}

	// 重写Enumeration判断元素存在的抽象方法
	@Override
	public boolean hasMoreElements() {
		// 返回属性类的判断元素方法
		return it.hasNext();
	}

	@Override
	// 重写Enumeration遍历下一个元素的抽象方法
	public Object nextElement() {
		// 返回属性类的遍历下一个元素方法
		return it.next();
	}
}
结果:ZhangSan
    Lisi
    WangWu

11  LinkedList实现类
 LinkedList是list实现类之一,它的数据结构是链表结构。特点是:增删快,查询慢,线程同步的,比较安全。
      LinkedList特有方法:
              void addFirst(Object)
              void addLast(Object)
              Object getFirst()
              Object getLast()
              Object removeFirst()
              Object removeLast()
              void push(Object o):压栈,就是把元素添加到0下标位置,与addFirst一样。
              Object pop():弹栈,就是把0下标位置的元素返回并移除。
    LinkedList实例:

import java.util.LinkedList;

public class LinkedListDemo {

	/**
	 * LinkedList数据结果是链表结构:
	 *而它在内存中操作的是栈,它的特性是"后进先出"
	 */
	public static void main(String[] args) {
		// 创建一个LinkedList集合
		LinkedList li = new LinkedList();
		// 压栈,压入元素
		li.push("张三");
		li.push("李四");
		li.push("王五");
		IQueue mi = new MyIQueue(li);
		// 利用多态,调用MyIQueue对象的mpty方法,判断集合是否不为空
		while (!mi.mpty()) {
			//打印弹栈元素
			System.out.println(mi.op());

		}
	}
}

// 定义一个接口,与三个方法
interface IQueue {
	void ph(Object obj);

	boolean mpty();

	Object op();
}

// 实现接口
class MyIQueue implements IQueue {
	// 定义一个LinkedList类型的属性并初始化
	private LinkedList lk = new LinkedList();;

	// 定义一个能接受LinkedList类型的构造器
	public MyIQueue(LinkedList lk) {
		this.lk = lk;
	}

	@Override
	// 实现接口的抽象方法
	public void ph(Object obj) {
		// 调用lk对象的push方法,让参数压栈
		lk.push(obj);
	}

	@Override
	// 实现接口的抽象方法
	public boolean mpty() {
		// 调用lk对象的isEmpty方法,判断集合是否为空
		return lk.isEmpty();
	}

	@Override
	// 实现接口的抽象方法
	public Object op() {
		// 调用lk对象的push方法,让元素弹栈
		return lk.pop();
	}

}
结果为:王五
       李四
       张三

12  泛型:
 1.什么是泛型?
    具有一个多个类型参数的类就是泛型。它的表现格式:<>
 2.泛型的好处
    1.在运行期间的问题ClassCastException问题转成编译失。败,体现在编译时期,程序员就可以解决问题。
    2.避免了强制转换的麻烦。
 3.泛型的运用
    泛型时在编译器使用的技术,到了运行时期,泛型就不存在了。这是因为泛型的擦除,编译器检查了泛型的类型正确后,在生成的类文件是没有泛型的。但当
    类型已经确定该了是同一个类型的元素,所以在运行时,只要获取到该元素的类型,就不需要转型了。
 4.泛型的使用
    当类中的操作的引用数据类型不确定的时候,以前用的Object来扩展的,现在可以用泛型来表示。这样避免强转的麻烦,而且将运行问题转移到到编译时期。

    泛型实例1:

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

public class GenericDemo {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		List<String> li = new ArrayList<String>();
		li.add("java");
		// li.add(100);如果插入的元素师int型,就会出现添加类型错误,因为已经定义了li集合对象是String类型的
		li.add("C++");
		li.add("php");
		// 迭代器也必须指定String泛型,这样避免了迭代出来的数据后,还得进行强转。
		Iterator<String> it = li.iterator();
		while (it.hasNext()) {
			// 此处在没有定义泛型之前必须进行强转,因为iterator的next方法迭代出来的数据是不确定的类型
			String string = it.next();
			System.out.println(string);

		}
	}

}
结果为:java
       C++
       php

泛型的限定:
     上限:<? extends T> 只能使用T类型或者T类型的子类对象。
     下限:<? super T> 只能使用T类型或者T的父类及接口实例对象

 上限什么时候用:往集合中添加元素时,既可以添加T类型对象,又可以添加E的子类型对象。为什么?因为取的时候,T类型既可以接受T类对象,又可以接收T的子类对象。
 下限什么时候用:当从集合中获取元素进行操作的时候,可以用当前元素的类型接受,也可以用当前元素的父类型接收。
    泛型实例2:

import java.util.ArrayList;
import java.util.List;

public class GenericDemo1 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		List<? extends Object> li = new ArrayList<String>();
		/*
		 * 这样添加是错误的,String虽然是Object的子类,但是Object的子类非常多,
		 * 你不确定它是哪个?既然不确定,又怎么添加具体类型的对象呢?
		 */
		// li.add("abc");
		List<? super String> lia = new ArrayList<Object>();
		/*
		 * 这样是可以的,下限。因为"abc"是字符串对象,而lia的集合规定了,只能添加String类型或者它的父类对象 ,所以是可以的
		 */
		lia.add("123");
		// 不可以在new的时候使用通配符。因为创建的时候,必须明确它的类型
		// ArrayList lib = new ArrayList<? extends Object>();
		List<?> list1 = new ArrayList();
		List<?> list2 = new ArrayList<String>();
		List<? extends Object> pList = new ArrayList<Object>();
		List<? super String> sList = new ArrayList<String>();
		List<?> list3 = sList;
		// list1.add("abc");error,因为list不确定是什么类型的集合。
		list2.isEmpty();// 这个可以是因为使用Object引用来指向isEmpty()方法的返回值了
		// list3.add(123);// 它是不确定的类型集合,既然不确定就不能添加具体的对象,而默认的是Object的类型。
	}

	// 可以在定义的时候使用通配符。因为你在给它传入参数的时候,指定了它的一个范围。
	public static void fun(List<? extends Object> list, String str) {
		// 只能对集合中的元素调用Object类中的方法,具体子类型的方法都不能用,因为子类型不确定。
		// 用Object的get方法引用指向了它的返回值
		System.out.println(list.get(0));
	}
}

总结:
1.可以使用List<? extends person>指向List<student>、List<person>、List<Employee>。只要元素类型为Person,或其子类就是可以的。
         2.可以使用List<? super student>指向List<student>、List<person>、List<Object>。只要元素类型为Student或Student父类就是可以的。
         3.注意:不能再new时使用通配符。
             new ArrayLsit<? extends person>(),这是不可以的!
         4.可以在定义引用时使用通配符:
             ArrayList<? extends Person>list;

----------- android培训java培训、java学习型技术博客、期待与您交流! ------------

抱歉!评论已关闭.