系统开始学后端

Java中的泛型以及常见数据结构

2018-08-11  本文已影响22人  DeeJay_Y

集合的体系结构形成的原因:

由于不同的数据结构,所以Java提供了不同的集合,但是不同的集合他们的功能都是相似的,向上提取共性,这就是集合体系结构形成的原因。

体系结构

从最顶层开始学习,因为其包含了所有的共性。使用从最底层开始使用,因为最底层才是最具体的实现。

来看集合体系结构中的最顶层 Collection:

Collection

几个共性的API

boolean add(E e)

boolean contains(Object o)

boolean isEmpty()

boolean remove(Object o)

int size()

Object[] toArray()

Iterator<E> iterator() // 返回一个迭代器对象

Interface Iterator<E>

用于迭代Collection

boolean hasNext() 如果有下一项,返回true

E next() 返回下一个元素,如果迭代完成继续迭代,会抛出异常

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

public class IteratorDemo {
    public static void main(String[] args) {
        Collection c = new ArrayList();
        
        for(int i = 0 ; i < 10; i ++) {
            c.add(i);
        }
        
        Iterator it = c.iterator(); // 返回一个迭代器对象
        
        while(it.hasNext()) {
            System.out.println(it.next());
        }
    }
}

关于迭代器,迭代器是依赖于集合的,相当于集合的一个副本。

当在迭代器在进行操作的时候,如果对集合进行改动,造成迭代器和集合不一样的时候,迭代器会抛出异常。

解决方案:

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

public class IteratorDemo {
    public static void main(String[] args) {
        Collection<String> c = new ArrayList<String>();
        c.add("Hello");
        c.add("java");
        
        Iterator<String> it = c.iterator();
        while(it.hasNext()) {
            if(it.next().equals("java")) {
                c.add("world"); // java.util.ConcurrentModificationException
            }
        }
        System.out.println(c);
    }
}

如上例所示,抛出了并发处理异常。

要使用迭代器完成对集合的改变,就不能使用Iterator<E>,因为其没有add方法,要使用ListIterator<E>。 要使用ListIterator,就得使用Collection的子体系结构List的ListIterator()方法来得到一个迭代器对象。具体来看例子:

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

public class IteratorDemo {
    public static void main(String[] args) {
//      Collection<String> c = new ArrayList<String>();
//      c.add("Hello");
//      c.add("java");
        // 使用List 而不是 Collection
        List<String> li = new ArrayList<String>();
        li.add("Hello");
        li.add("java");
        
//      Iterator<String> it = c.iterator();
        ListIterator<String> listIt = li.listIterator(); // ListIterator 具有add方法
//      while(it.hasNext()) {
//          if(it.next().equals("java")) {
//              c.add("world"); // java.util.ConcurrentModificationException
//          }
//      }
        while(listIt.hasNext()) {
            if(listIt.next().equals("java")) {
                listIt.add("world"); // 这样就可以操作迭代器而不是直接操作集合  就不会抛出异常
            }
        }
        System.out.println(li); // [Hello, java, world] 正常输出

    }
}

集合的遍历方式

  1. toArray(),将集合转换为数组,遍历数组
  2. iterator(),可以返回一个迭代器对象,可以通过迭代器对象来迭代集合
import java.util.Collection;
import java.util.ArrayList;
import java.util.Iterator;

public class IteratorDemo {
    public static void main(String[] args) {
        Collection c = new ArrayList();
        
        for(int i = 0 ; i < 10; i ++) {
            c.add(i);
        }
        // method1();
        // method2();
    }
    public void method1(Collection c) { // 使用Iterator
        Iterator it = c.iterator(); // 返回一个迭代器对象
        
        while(it.hasNext()) {
            System.out.println(it.next());
        }
    }
    
    public void method2(Collection c) { // 使用toArray()
        Object[] objArr = c.toArray();
        for(int i = 0 ; i < objArr.length; i ++) {
            System.out.println(objArr[i]);
        }
    }
}

泛型的概述和体现

由于集合是可以存储任意类型的对象的,所以当存储了不同类型的对象时,就有可能在进行转换时出现类型转换类型异常ClassCastException。所以Java提供了泛型。

泛型:是一种广泛的类型,将明确数据类型的工作提前到了编译时期,借鉴了数组的特点。

泛型的优点:

使用泛型的场景:

来看一个简单的例子:

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

public class GenericDemo {
    public static void main(String[] args) {
        Person p1 = new Person("zhangsan",18);
        Person p2 = new Person("lisi",20);
        
        Collection<Person> c = new ArrayList<Person>(); // 使用泛型 表明集合中存储Person类型的对象
        c.add(p1);
        c.add(p2);
        
        Iterator<Person> it = c.iterator(); // 使用泛型  表明迭代器中的类型也是Person类
        while(it.hasNext()) {
            it.next().show(); // 注意使用了泛型之后  这边的it.next() 返回的已经是Person类的对象了  直接直接调用方法。
        }
    }
}

class Person {
    String name;
    int age;
    public void show() {
        System.out.println(name + "---" + age);
    }
}

foreach()

增强for循环,一般用于遍历集合或者数组

语法:

for(Type var : CollectionOrArray) {
    // 可以直接使用var
}

来看一个例子:

Collection<String> c = new ArrayList<String>();
c.add("hello");
c.add("java");

for(String str : c) {
    System.out.print(str.toUpperCase()); // HELLO JAVA
}

注意点: 在增强for循环中不可以修改集合,否则也会出现并发修改异常,因为其底层结构就是迭代器。

常见数据结构:

数组:

int[] arr = {1,2,3,4,5};

数组的特点:

一些问题:

可以看到,数组查找快,但是增删慢

链表:

由链连接起来的一堆结点

结点分为三部分:

  1. 地址值
  2. 下一个结点的地址值

假设现在有一个链表:
按照地址值,值,下一个地址值来表示:

0x0011 1 0x0022
0x0022 2 0x0033
0x0033 3 0x0044
0x0044 4 0x0055
0x0055 5 最后一个结点

一些问题:

可以看到: 链表查找慢,增删快

java中运行方法就会进栈,运行完后就会出栈。

特点:先进后出

跟弹夹差不多,先压进去的子弹最后被射出来。

队列

特点: 先进先出

类比现实生活中排队

java.util.List

List是Collection的子体系结构

并发修改异常处理中就使用过List的ListIterator()方法。简单介绍一下:

特点:

List由于具有索引,所以相比于Collection具有一些特有功能:

package ListDemo;

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

public class ListDemo {
    public static void main(String[] args) {
        List<String> li = new ArrayList<String>();
        
        // void add(int index, E element)
        li.add("Hello");
        li.add(0,"world");
        li.add(0,"java");
        System.out.println(li); // [java, world, Hello] 每次指定索引时,之前的元素向后移动
        
        
        // E get(int index)
        System.out.println(li.get(2)); // Hello
        
        // E remove(int index)
        System.out.println(li.remove(2)); // Hello
        System.out.println(li); // [java, world]
        
        // E set(int index, E element) 
        System.out.println(li.set(0,"Python")); // java
        System.out.println(li); // [Python, world]
    }
}

关于java.util.List常见的子类

一般常见的子类有俩:

根据使用场景来使用不同的子类,一般不确定使用啥就使用ArrayList

java.util.LinkedList

链表结构常见的几个api:

package ListDemo;

import java.util.LinkedList;

public class LinkedListDemo {
    public static void main(String[] args) {
        LinkedList<Integer> li = new LinkedList<Integer>();
        
        for (int i = 0; i < 10; i++) {
            li.add(i);
        }
        
        System.out.println(li); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        
        // void addFirst(E e)
        li.addFirst(-1);
        System.out.println(li); // [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
        
        // void addLast(E e)
        li.addLast(10);
        System.out.println(li); // [-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

        // E getFirst() E getLast()
        System.out.println(li.getFirst());// -1
        System.out.println(li.getLast()); // 10
        
        // E removeFirst() E removeLast()
        System.out.println(li.removeFirst()); // -1
        System.out.println(li); // [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
        System.out.println(li.removeLast()); // 10
        System.out.println(li); //[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

    }
}

上一篇 下一篇

猜你喜欢

热点阅读