400-616-5551

您所在位置: 首页> 学习课程> java培训 | List实现类性能和特点分析,掌握java必备

java培训 | List实现类性能和特点分析,掌握java必备

发布百知教育 来源:学习课程 2019-10-12

java培训


面向接口编程:

接口类型变量 = new 实现类();

List  list = new ArrayList();

List实现类特点和性能分析: 

三者共同的特点共同遵循的规范:

1)允许元素重复;

2)记录元素的先后添加顺序;

Vector类:底层采用数组结构算法,方法都使用了synchronized修饰,线程安全,但是性能相对于ArrayList较低。

Arraylist类:底层采用数组结构算法,方法没有使用synchronized修饰线程不安全,性能相对于vector较高。

ArrayList现在几乎已经取代了Vector的江湖地位。

了保证ArrayList的线程安全,List list = Collections.synchronizedList(new ArrayList(..);

LinkedList类:底层采用双向链表结构算法方法没有使用synchronized修饰,线程不安全;


数组结构算法和双向链表结构算法的性能问题:

数组结构算法:插入和删除操作速度低,查询和更改较快;

链表结构算法:插入和删除操作速度快,查询和更改较慢;


使用的选择:

Vector类不用不用,即使要用选ArrayList类。

如果删除和插入操作频繁应该选择LinkedList类。

如果查询操作频繁,应该使用ArrayList类。

在开发中使用ArrayList较多,根据具体的需求环境来做选择。


集合的迭代操作


集合的迭代操作:把集合做的元素一个一个的遍历取出来。


package com_520it_day02_iterator;


import java.util.ArrayList;

import java.util.List;


//集合元素的迭代/遍历操作

public class IteratorDemo {

  public static void main(String[] args) {

    List list = new ArrayList();

    list.add("A");

    list.add("B");

    list.add("C");

    list.add("D");


    //方式1:for循环

    for (int index = 0; index < list.size(); index++) {

      Object ele = list.get(index);//取出指定索引位置的元素

      System.out.println(ele);

    }

    System.out.println("---------------------");

    //方式2:for-each增强for循环

    /*

       for(类型  变量 :数组名/Iterable的实例){

         //TODO

        }

     */

    for (Object ele : list) {

      System.out.println(ele);

    }


  }

}

迭代器对象:Iterator:迭代器对象,只能从上往下迭代;

boolean hasNext(): 判断当前指针后是否有下一个元素;

Object next():获取指针的下一个元素,并且移动指针。

ListIterator:是Iterator接口的子接口,支持双向迭代,从上往下

迭代从下往上迭代;

    //方式3:使用迭代器Iterator

    Iterator it = list.iterator();

    while (it.hasNext()) {

      Object ele = it.next();

    }

    //方式4:使用for循环来操作迭代器Iterator

    for (Iterator it2 = list.iterator(); it2.hasNext();) {

      System.out.println(it2.next());

    }

Enumeration:古老的选代器对象现在已经被lterator取代了。适用于古老的Vector类。

package com_520it_day02_iterator;


import java.util.Enumeration;

import java.util.Vector;


public class EnumerrationDemo {

  public static void main(String[] args) {

    Vector v = new Vector();

    v.add("A");

    v.add("B");

    v.add("C");

    v.add("D");

    //迭代操作

    for (Enumeration en = v.elements(); en.hasMoreElements();) {

      Object ele = en.nextElement();

      System.out.println(ele);

    }

  }

}


深入分析for- each和迭代器

1)for-each可以操作数组:

底层依然采用for循环+索引来获取数组元素。


java培训


2)for-each可以操作Iterable的实例:底层其实采用的Iterator(迭代器),直接使用for-each迭代数组和集合元素即可,更简单。

for(类型  变量 :数组名/Iterable的实例){

     //TODO

}


java培训班


当需要边迭代边删除指定的集合元素时:此时只能使用迭代器。而且只能使用迭代器对象的remove方法。


java培训班


当使用迭代的时候,在当前线程A中,会单独创建一个新的线程B。A线程负责继续迭代B线程负责去删除。


B线程每次都会去检查和A线程中的元素是否个数相同,如果不是,报错:


ConcurrentModificationException。


java培训班


在迭代集合的时候边迭代边删除是非常常用的操作:

如何解决并发修改异常呢?


不要使用集合对象的删除方法。在collection接口中存在删除指定元素的方法:boolean remove(Object ele); 该方法只能从集合中删除元素,不能把迭代器中指定的元素也删除。


我们应该使用Iterator中的remove方法。该方法会从两个线程中同时移除被删除的元素,保证了两个线程的同步。


java培训


泛型操作


为什么需要使用泛型:

1)存储任意类型(Object)的数据在集合中,但是取出来都是Object类型的,此时就得强转。



2)约束存储到集合中的元素必须是相同的数据类型(相同的数据类型才能做比较)比如TreeSet类;


java培训


3)设计一个点(Point)类,来封装坐标位置,要求坐标位置支持String类型、Integer类型、Double类型。非常不优雅的设计,如下图(重复定义)


java培训


泛型(GenericType),从Java5开始支持的新的语法:


什么是泛型:


        1)广泛通用的类型;

        2)代码模板中类型不确定,谁调用该段代码,谁指明类型是什么。


java培训


泛型类:直接在类/接口上定义的泛型。


使用泛型:保证前后类型相同


List<String> list = new ArrayList<String>();//该List集合中只能存储String类型的元素.

因为前后类型相同,所以从Java7开始,推出出泛型的菱形语法<>。


List<String> list = new ArrayList<>();

泛型不存在继承的关系(错误如下):

List<Object> list = new ArrayList<String>();//错误的

从此以后,使用集合都得使用泛型来约束该集合中元素的类型。


通过反编译发现:泛型其实也是语法糖,底层依然没有泛型,而且依然使用强转。


java培训


泛型方法:在方法上声明泛型。

情况1 )泛型类中的泛型只能适用于非静态方法,如果需要给静态方法设置泛型,此时使用泛型方法;


情况2)泛型类中的泛型应该适用于整个类中多个方法,有时候只对某一个方法设置泛型即可。


一般的,把自定义的泛型作为该方法的返回类型才有意义,而且此时的泛型必须是由参数设置传进来的。如果没有参数来设置泛型的具体类型,此时的方法一般返回设计为Object即可。


泛型的通配符和上限和下限:


泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用?表示未知通配符。此时只能方法中接受传入的数据,不能往该集合中存储数据。



泛型的上限和下限:用来限定元素的类型,必须是X类的子类或者相同,X的父类或相同。


java培训


泛型擦除和转换:

泛型的擦除:

1)泛型编译之后就消失了(泛型自动擦除);

2)当把带有泛型的集合赋给不带泛型的集合,此时泛型被擦除(手动擦除)。


堆污染:

单一个方法既使用泛型的时候也使用可变参数,此时容易导致堆污染问题。如:在Arrays类中的asList方法:public static <T> List<T> asList(T... arr).

package com_520it_day02_generictype;


import java.util.List;

import java.util.ArrayList;


public class GenericTypeDemo2 {

  public static void main(String[] args) {

    //带有Integer泛型

    List<Integer> list1 = new ArrayList<>();

    list1.add(123);

    //list1.add("ABC");//此时报错


    //不带有泛型

    List list2 = list1;//此时泛型被檫除

    list2.add("ABC");//验证无错


    //带有String泛型

    List<String> list3 = null;

    list3 = list2;//此时只是绕开立刻编译器的检查,有问题。这就是堆污染


    //报错:java.lang.Integer cannot be cast to java.lang.String

    String num = list3.get(0);//取出123  等价于:String String = 123;报错

  }

}


java培训:http://www.baizhiedu.com/java2019



上一篇:java培训 | Java中的运算符你了解多少?

下一篇:应届生去公司找个Java程序员的职位需要什么技能?

相关推荐

www.baizhiedu.com

有位老师想和您聊一聊

关闭

立即申请