----------- 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学习型技术博客、期待与您交流! ------------