java学习笔记(Core Java) 9 泛型

集合接口
一、引言:
接口与实现分离,使用队列举例
//提供接口规范
interface Queue
{...}
//具体实现
class LinkedListQueue<E> impements Queue<E> {...}
class CircularArrayQueue<E> impements Queue<E> {...}

Queue<Customer> e = new LinkedListQueue<Customer>

二、迭代器
1.集合类基本接口是Collection,该接口包括两种基本方法:
public interface Collection
{
boolean add(E element);
Iterator<E> iterator();
...
}

public interface Iterator<E>
{
E next();
boolean hasNext();
void remove();
}
在javase 5.0起,可以使用for each的方式循环操作
for each可以与任何实现了Iterable接口的对象一起工作
public interface Iterable<E>
{
iterator<E> iterator();
}

C++:与C++不同。c++迭代器指针可以单独的在stl模板上进行移动。
for(vector<int>::Iterable it = vect.begin(); it != vect.end(); it++) 通过对指针解引用可以获取指针所引用对象的值
但是java不同,java遍历整个集合时,必须调用next方法,指针才会向下移动。每次移动之前,都需要hasNext判断下一个值是否存在。从某种意义上说。查找操作指针移动时紧密相连的。

2.删除元素
iterator接口中remove方法时删除上次next方法返回时的元素。因此在调用remove方法时,必须首先要调用next方法。
3.泛型的实用方法(举例)
public static <E> boolean contains(Collection<E> c, object obj)
{
for(E element:c)
if(element.equal(obj))
return true;
return false;
}
Collection接口声明的很多类似于上述的泛型方法
比Collection更容易实现的抽象类
public abstract class AbstractCollection<E> implements Collection<E>
{
public abstract Iterator iterator();
public boolean contance(object obj)
{
for(E element:c)
if(element.equal(obj))
return true;
return false;
}
...
}
//api 原书 567页

三、具体集合
ArrayList 索引 vector
LinkedList 高效插入删除 List
ArrayDeque 循环数组 双端队列
HastSet 没有重复元素的无序集合
TreeSet 有序集合
EmnuSet 包含枚举类型的集
LinkedHastSet 记住元素插入次序的集合
PriorityQueue 允许高效删除最小元素的集合
HastMap 键值对
TreeMap 有序排列的映射表
LinkedHastMap 记住键值对插入次序的集合
WeakHashMap 值无效可以被垃圾回收期回收的映射表
IdentityHaspMap 使用==而不是equals比较键值的映射表

set是没有重复的元素集合

1.链表:
链表是一个有序集合,因此可以使用add方法将元素插入链表的任意位置。对于无序的集合HastSet则没有该方法
ListIterator接口中也有两个方法用于逆向遍历
E previous(); 反向遍历元素
boolean hasPrevious()

remove始终删除上一次 next/previous 刚刚遍历的元素
add方法依赖于迭代器的位置
remove方法依赖于迭代器的状态

set的方法用于替换 next/previous 刚刚遍历的元素
ListIterator<String> iter = list.listIterator();
String oldValue = iter.next();
iter.set(newValue);

迭代器指向两个元素之间,因此可以返回两个指向的对象。使用nextIndex方法返回下一个将要遍历的元素的整数索引。previous返回刚刚遍历元素的整数索引

get方法,效率不高。。。
简单例子:
List<String> a = new LinkedList();
a.add("hh")
ListIterator<String> iter = a.listIterator();
while(iter.hasNext())
{
a.next();
a.remove();
}

//api 原书 575页

C++:
list<string> list;
list<string>::iterator iter;

list.push_back("hh");

for(it = list.begin(); it != list.end; it++)
{
std::cout << *it << std::end;
}

2.数组列表 ArrayList
与list相同。但是,对于以数组为底层封装的列表来说,set/get方法将变得非常有用

3.散列集 快速查找需要的对象
散列表为每个对象计算一个整数,成为散列码
散列码是由对象的实际域产生的一个整数
具有不同数据域的对象将产生不同的散列码
(如果自定义域,就要实现HashCode方法。实现的方法要与equal方法相同,即a.equal(b)为true时,a,b必须有相同的散列码) ==》具体第五章

散列表使用链表数组实现。每个列表称之为桶。要查找表中对象的位置,就要计算它的散列码,然后与桶的余数取余。得到该对象元素的索引。

set是没有重复的元素集合。contains方法重新定义可以快速查看元素是否已经插入。使用add方法添加元素。它的访问顺序几乎是随机的。

//api 原书 578页

4.树集
TreeSet与散列集十分类似,它是一个有序集合,可以以任意顺序将元素插入集合。遍历时将依次访问。

将元素添加到TreeSet比添加到散列表慢,但是比将元素添加到链表或数组的正确位置上还是快很多。并且,TreeSet还可以自动排序

TreeSet();
TreeSet(Collection<? extends E> elements);

5.对象的比较 compareTo方法和equal方法

6.队列与双端队列 (不支持在队列中间添加元素)
Javase6 引入了Deque接口,并由ArrayDeque和LinkedList类实现

api:
//如果满了,抛出异常IIlegalStateException
boolean add(E element);
//如果满了,返回false
boolean offer(E element);

//如果不为空,删除并返回头部元素,如果为空,抛出异常NoSuchElementException
E remove();
//同上,如果为空,返回null
E poll();

//如果不为空,返回头部元素不删除,如果为空,抛出异常NoSuchElementException
E element();
//同上,如果为空,返回null
E peek();

//如果满了,抛出异常IIlegalStateException
void addFirst(E element)
void addLast(E element)
//如果满了,返回false
boolean offerFirst(E element)
boolean offerLast(E element)

//如果不为空,删除并返回头部元素,如果为空,抛出异常NoSuchElementException
E removeFirst();
E removeLast();
//同上,如果为空,返回null
E pollFirst();
E pollLast();

//如果不为空,删除并返回头部元素,如果为空,抛出异常NoSuchElementException
E getFirst();
E getLast();
//同上,如果为空,返回null
E peekFirst();
E peekLast();

ArrayDeque();
ArrayDeque(int initialCapacity);
//初始容量16或给定初始容量构造一个无限双端队列

7.优先级队列
元素可以任意顺序输入,却总是按照排序顺序检索。无论何时调用remove方法,总是会获取当前优先级队列中最小元素,但是,优先级队列并没有进行排序。
使用数据结构==》 堆
堆是一个可以自我调整的二叉树。可以让最小元素移动到树根而不必花时间进行排序。

典型案例: 任务调度
PriorityQueue();

//构造一个用于存放Compareable对象的优先级队列
PriorityQueue(int initialCapacity);
//构造一个优先级队列,并用指定比较器对元素排序
PriorityQueue();

8.映射表 键值对 --------------字典
HashMap(散列映射表)和TreeMap(树映射表),这两个类都实现了Map接口
散列映射表对键进行散列
树映射表用键的整体顺序进行排序,并组成搜索树

散列稍微快一点,如果不需要按照顺序访问,最好选择散列

put方法新增或者更改键对应的值
remove();删除键对应的值 size();//返回元素个数

时间: 2024-10-13 06:59:52

java学习笔记(Core Java) 9 泛型的相关文章

java学习笔记(Core Java) 8 泛型

泛型一.定义一个泛型类public class Pair<T>{ private T _first; public Pair(T first) {this._first = first;} public T getfirst() {return _first;}}java中类型变量使用大写字母且比较短E:元素类型 K,V 表的关键字与值的类型 T(U/S)任意类型 泛型方法:要么返回类型是泛型,要么参数是泛型public static <T> getMiddle(T... a){

java学习笔记(Core Java) 6接口与内部类

接口(实现C++的多继承,同时避免了虚继承)深拷贝与浅拷贝内部类代理 一.接口与泛型接口:提供一组行为规范public interface Comparable<T>{ int compareTo(T other)}...int conpareTo<Employee other> //指定T 接口中所有的方法自动属于public所有的域自动为public staic 接口中的域自动声明为 public static final 继承接口的关键字:implements1.接口提供方法

java学习笔记3——java关键字

java学习笔记3——java关键字 虽然老师说不用刻意的去记忆,但是我还是在网上找到了非常详细的注解,再次收藏 关键字的类型表: 各个关键字的详细注解和实例,按首字母排序: 1.abstract abstract 关键字可以修改类或方法. abstract 类可以扩展(增加子类),但不能直接实例化. abstract 方法不在声明它的类中实现,但必须在某个子类中重写. -示例- public abstract class MyClass{ } public abstract String my

Java学习笔记(Java语言规范,API,JDK,IDE)

Java语言规范:java.sun.com/docs/books/jls 三个版本的API:J2SE J2EE J2ME 1. J2SE 客户端独立应用程序或者applet 2. J2EE 服务端应用程序 [Java Servlets&JavaServer Page] 3. J2ME 移动设备变成 JDK为Java开发提供一个开发环境(IDE) Java学习笔记(Java语言规范,API,JDK,IDE)

JAVA学习笔记(五十六)- 泛型 Generic Types

泛型 Generic Types import java.util.ArrayList; import java.util.List; /* * 泛型 Generic Types * 集合泛型 * 类泛型 * 方法泛型 */ public class Test01 { public static void main(String[] args) { // 1.集合泛型,保证集合中元素的类型安全 List<Integer> nums = new ArrayList<Integer>(

java学习笔记1——java环境的搭建

1.java的安装路径最好没有中文和空格,因为如果有中文或者空格,在以后的编译过程中很容易出现莫名其妙的错误 2.安装java的过程中,安装好jdk后弹出安装JRE的界面,此时不用继续安装直接退出即可,因为JDK包含JRE,就算再装JRE,也是与JDK中的JRE是一样的 3.java环境搭建的原因,是为了方便程序编译的时候可以直接在DOS命令中输入java相关的命令就可以直接调用,而不需要每次都要尽到java命令所在的目录,因为当你输入此命令时,windows会找两次,第一次在你输入的目录中寻找

Java学习笔记-7.Java IO流

一.输入/输出流 1.流:不同类型的输入.输出源    数据流:输入或输出的数据 Java数据流的所有接口和类都是在java.io包中定义的,因此应在程序开头加入 import java.io.* 2.流的分类: (1)从流的流动方向来看,可以将IO流分为输入流和输出流 输入流:数据信息从某个地方流向程序中 输出流:数据信息从程序中发送到某个目的地 (2)从流的数据处理单位来看,可以将IO流分为字节流和字符流 字节流:以字节方式处理的二进制数据 字符流:以字符方式处理的数据流(Java使用Uni

java学习笔记9.22(泛型)

泛型代码与虚拟机: 自动提供原始类型,擦除类型变量,替换为限定类型(无则用object) 当调用泛型方法时,编译器对返回的object进行强制类型转换 泛型类擦除造成原本在泛型类子类中覆盖的方法变成了重载.(参数类型变成了object)导致子类出现了同一方法名两种参数的方法,调用时本来只希望调用子类的方法(多态),结果有可能调用了泛型超类中的参数为objec的方法.编译器自动在子类中加入桥方法: public void setSecond(object a){setSecond((Date) a

Java学习笔记-2.Java语言基础

一.命名规则 1.Java标识符 Java所有的组成部分都需要名字.类名.变量名以及方法名都被称为标识符. 关于Java标识符,有以下几点需要注意: 所有的标识符都应该以字母(A-Z或者a-z),美元符($).或者下划线(_)开始 首字符之后可以是任何字符的组合 关键字不能用作标识符 标识符是大小写敏感的 合法标识符举例:age.$salary._value.__1_value 非法标识符举例:123abc.-salary 2.注意: 大小写敏感:Java是大小写敏感的,这就意味着标识符Hell