Java集合、迭代器、泛型、线程体系结构

集合

Java中集合继承关系:

  • List , Set, Map都是接口,前两个继承至Collection接口,Map为独立接口
  • Set下有HashSet,LinkedHashSet,TreeSet
  • List下有ArrayList,Vector,LinkedList
  • Map下有Hashtable,LinkedHashMap,HashMap,TreeMap
  • Collection接口下还有个Queue接口,有PriorityQueue类

1.Set

TreeSet:基于红黑树实现,支持有序性操作,例如根据一个范围查找元素的操作。但是查找效率不如 HashSet,HashSet 查找的时间复杂度为 O(1),TreeSet 则为 O(logN)。

HashSet:基于哈希表实现,支持快速查找,但不支持有序性操作。并且失去了元素的插入顺序信息,也就是说使用 Iterator 遍历 HashSet 得到的结果是不确定的。

LinkedHashSet:具有 HashSet 的查找效率,并且内部使用双向链表维护元素的插入顺序。

2.List

ArrayList:基于动态数组实现,支持随机访问。

Vector:和 ArrayList 类似,但它是线程安全的。

LinkedList:基于双向链表实现,只能顺序访问,但是可以快速地在链表中间插入和删除元素。不仅如此,LinkedList 还可以用作栈、队列和双向队列。

3.Queue

LinkedList:可以用它来实现双向队列。

PriorityQueue:基于堆结构实现,可以用它来实现优先队列。

迭代器

Iterator作为一个接口存在,源码如下

package java.util;
public interface Iterator<E> {
	boolean hasNext();
	E next();
	void remove();
}

iterator实现源码:

private class Itr implements Iterator<E> {  
	int cursor = 0;  
    int lastRet = -1;  
    int expectedModCount = modCount;  
    public boolean hasNext() {  
    	return cursor != size();  
    }  
  
    public E next() {  
        checkForComodification();  
        try {  
            int i = cursor;  
            E next = get(i);  
            lastRet = i;  
            cursor = i + 1;  
            return next;  
        } catch (IndexOutOfBoundsException e) {  
            checkForComodification();  
            throw new NoSuchElementException();  
        }  
    }  
  
    public void remove() {  
        if (lastRet < 0)  
            throw new IllegalStateException();  
        checkForComodification();  
  
        try {  
            AbstractList.this.remove(lastRet);  
            if (lastRet < cursor)  
                cursor--;  
            lastRet = -1;  
            expectedModCount = modCount;  
        } catch (IndexOutOfBoundsException e) {  
            throw new ConcurrentModificationException();  
        }  
    }  
  
    final void checkForComodification() {  
        if (modCount != expectedModCount)  
            throw new ConcurrentModificationException();  
    }  
 }  

其中的重点是定义了expectedModCount,提供了一种Fast-Fail机制,用来保证迭代过程中集合的安全性。当集合进行修改时(包括改变集合结构、改变集合大小、打乱集合中的顺序等,不包括设置元素的值),modCount会增加,迭代器会将expectedModCount与modCount比对来看是否正确。如下操作就会报java.util.ConcurrentModifcationException:

List<String> list = new LinkedList<String>();
list.add("first");
list.add("second");
for(Iterator<String> iter = list.iterator();iter.hasNext();) {
    String str = (String)iter.next();
    System.out.println(str);
    if(str.equals("second")) {
        list.add("three");
    }
}

Iterator和ListIterator的区别:

Iterator:正向遍历、获取和移除元素

ListIterator:双向遍历、支持元素修改

泛型

泛型有三种使用方式:泛型类、泛型接口、泛型方法

泛型只在编译阶段有效,编译时正确检验类型结果后,会将泛型的相关信息擦出,并且在对象进入和离开方法的边界处添加类型检查和类型转换的方法。

List<String> stringArrayList = new ArrayList<String>();
List<Integer> integerArrayList = new ArrayList<Integer>();

Class classStringArrayList = stringArrayList.getClass();
Class classIntegerArrayList = integerArrayList.getClass();

if(classStringArrayList.equals(classIntegerArrayList)){
    Log.d("泛型测试","类型相同");
}

泛型类

泛型类型用于类的定义中,被称为泛型类。 基本写法:

class 类名称 <泛型标识:可以随便写任意标识号,标识指定的泛型的类型>{
  private 泛型标识 /*(成员变量类型)*/ var; 
  .....

  }
}

example:

//此处T可以随便写为任意标识,常见的如T、E、K、V等形式的参数常用于表示泛型
//在实例化泛型类时,必须指定T的具体类型
public class Test<T>{ 
    //key这个成员变量的类型为T,T的类型由外部指定  
    private T key;

    public Generic(T key) { //泛型构造方法形参key的类型也为T,T的类型由外部指定
        this.key = key;
    }

    public T getKey(){ //泛型方法getKey的返回值类型为T,T的类型由外部指定
        return key;
    }
}

Test<Integer> testInteger = new Test<Integer>(12345);
Test<String> testString = new Test<String>("keyValue");
Log.d("泛型测试","key is" + testInteger.getKey());
//结果输出:泛型测试: key is 12345
Log.d("泛型测试","key is" + testString.getKey());
//结果输出:泛型测试: key is keyValue

注意:1、泛型的类型参数只能是类类型,不能是基本类型

2、不能对确切的泛型类型使用instanceof操作,如num instanceof Test,这种操作编译时会出错

泛型接口

泛型接口与泛型类的定义及使用基本相同。泛型接口常被用在各种类的生产器中,可以看一个例子:

//定义一个泛型接口
public interface Generator<T> {
    public T next();
}

当实现泛型接口的类,未传入泛型实参时:

/**
 * 未传入泛型实参时,与泛型类的定义相同,在声明类的时候,需将泛型的声明也一起加到类中
 * 即:class FruitGenerator<T> implements Generator<T>{
 * 如果不声明泛型,如:class FruitGenerator implements Generator<T>,编译器会报错:"Unknown class"
 */
class FruitGenerator<T> implements Generator<T>{
    @Override
    public T next() {
        return null;
    }
}

当实现泛型接口的类,传入泛型实参时:

/**
 * 传入泛型实参时:
 * 定义一个生产器实现这个接口,虽然我们只创建了一个泛型接口Generator<T>
 * 但是我们可以为T传入无数个实参,形成无数种类型的Generator接口。
 * 在实现类实现泛型接口时,如已将泛型类型传入实参类型,则所有使用泛型的地方都要替换成传入的实参类型
 * 即:Generator<T>,public T next();中的的T都要替换成传入的String类型。
 */
public class FruitGenerator implements Generator<String> {

    private String[] fruits = new String[]{"Apple", "Banana", "Pear"};

    @Override
    public String next() {
        Random rand = new Random();
        return fruits[rand.nextInt(3)];
    }
}

泛型通配符

我们知道Integer是Number的子类,那在使用 Test作为形参的函数中,能不能够传入Test使用呢?比如:

public void showKeyValue(Test<Number> obj){
    System.out.println("泛型测试:key value is " + obj.getKey());
}

Test<Integer> testInt = new Test<Integer>(12);
Test<Number> testNumber = new Test<Number>(34);
showKeyValue(testNumber);
showKeyValue(testInt);
//showKeyValue(testInt)这个会报错:cannot be applied to Test<java.lang.Number>

由此可以看出,同一种泛型可以对应多种版本,但不同版本的实例是不兼容的。这种问题不就违背了多态的设计理念了吗?因此,我们可以使用类型通配符来解决这种问题。

public void showKeyValue(Test<?> obj){
    System.out.println("泛型测试:key value is " + obj.getKey());
}

类型通配符一般是使用?代替具体的类型实参,注意了,此处’?’是类型实参,而不是类型形参 。此处的?和Number、String、Integer一样都是一种实际的类型,可以把?看成所有类型的父类。是一种真实的类型。

可以解决当具体类型不确定的时候,这个通配符就是 ? ;当操作类型时,不需要使用类型的具体功能时,只使用Object类中的功能。那么可以用 ? 通配符来表未知类型。

泛型方法

线程体系结构

·Executor:线程池顶级接口,只定义了一个执行无返回值任务的方法;

·ExecutorService:线程池次级接口,对Executor做了一些扩展,增加了关闭线程池、执行有返回值任务、批量执行任务的方法;

·ScheduledExecutorService:对ExecutorService做了一些扩展,增加了定时任务功能,分执行一次和重复执行多次两种;

·AbstractExecutorService:实现ExecutorService接口的抽象类,实现了部分方法,主要为执行有返回值任务和批量执行任务的方法;

·ThreadPoolExecutor:继承AbstractExecutorService类的普通线程池类,线程池的主要实现逻辑都在这里面,包括创建线程、处理任务、拒绝的策略等;

·ScheduledThreadPoolExecutor:定时任务线程池类,继承了ThreadPoolExecutor,实现了ScheduledExecutorService,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
辽B代驾管理系统对代驾订单管理、用户咨询管理、代驾订单评价管理、代驾订单投诉管理、字典管理、论坛管理、公告管理、新闻信息管理、司机管理、用户管理、管理员管理等进行集中化处理。经过前面自己查阅的网络知识,加上自己在学校课堂上学习的知识,决定开发系统选择小程序模式这种高效率的模式完成系统功能开发。这种模式让操作员基于浏览器的方式进行网站访问,采用的主流的Java语言这种面向对象的语言进行辽B代驾管理系统程序的开发,在数据库的选择上面,选择功能强大的Mysql数据库进行数据的存放操作。辽B代驾管理系统的开发让用户查看代驾订单信息变得容易,让管理员高效管理代驾订单信息。 辽B代驾管理系统具有管理员角色,用户角色,这几个操作权限。 辽B代驾管理系统针对管理员设置的功能有:添加并管理各种类型信息,管理用户账户信息,管理代驾订单信息,管理公告信息等内容。 辽B代驾管理系统针对用户设置的功能有:查看并修改个人信息,查看代驾订单信息,查看公告信息等内容。 辽B代驾管理系统针对管理员设置的功能有:添加并管理各种类型信息,管理用户账户信息,管理代驾订单信息,管理公告信息等内容。 辽B代驾管理系统针对用户设置的功能有:查看并修改个人信息,查看代驾订单信息,查看公告信息等内容。 系统登录功能是程序必不可少的功能,在登录页面必填的数据有两项,一项就是账号,另一项数据就是密码,当管理员正确填写并提交这二者数据之后,管理员就可以进入系统后台功能操作区。项目管理页面提供的功能操作有:查看代驾订单,删除代驾订单操作,新增代驾订单操作,修改代驾订单操作。公告信息管理页面提供的功能操作有:新增公告,修改公告,删除公告操作。公告类型管理页面显示所有公告类型,在此页面既可以让管理员添加新的公告信息类型,也能对已有的公告类型信息执行编辑更新,失效的公告类型信息也能让管理员快速删除。新闻管理页面,此页面提供给管理员的功能有:新增新闻,修改新闻,删除新闻。新闻类型管理页面,此页面提供给管理员的功能有:新增新闻类型,修改新闻类型,删除新闻类型。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值