一、泛型

1、泛型类

泛型是带一个或者多个类型参数的类或接口。在Java集合框架中大多数的类和接口都是泛型类型。下面看一下泛型例子:

public class Fan<T>{
    private T value;
    public Fan(){};
    public Fun(T value){
        this.value=value;
    }
    public T getter(){
        return value;
    }
    public void setter(T value){
        this.value=value;
    }
    
}

/******************************/
//测试类
/******************************/
public class Demo {
	 public static void main(String[] args){
		 Fun<Integer> fun=new Fun<>();
		 fun.setter(50);
		 System.out.println(fun.getter());
	 
	 }
}

/*输出结果*/
//50

        一旦创建了fun对象,就可以调用setter()方法设置其中的值(value),也就是Integer对象。但是如果输入的数据不与T在这里所代表的数据类型一致,就会发生错误。

         从JavaSE7开始,在创建泛型类型时可以使用菱形语法,也就是在创建时只在前一个菱形括号里写类型标识符,如下:

Fun<Integer> fun=new Fun<>();

        “T”在Java中叫做通配符,表示类型,除了T以外还有E(表示元素)、K(表示键)、N(表示数字)、V(表示值)、?(表示任意类型)。泛型可能具有多个类型参数,但在类或者接口的声明中,每个参数名必须是唯一的。

2、泛型方法

        泛型方法是带类型参数的方法。类的成员方法和构造方法都可以定义为泛型方法。泛型方法的定义与泛型类的定义类似,只是类型参数的作用域不同。下面是例子:

public class Util{
    public static <T> void swap(T[] array,int i,int j){
        T temp=array[i];
        array[i]=array[j];
        array[j]=temp;
    }
    
    
    public static void main(String[] args) {
    	Integer[] numbers= {1,3,5,7};
    	Util.<Integer>swap(numbers,0,3);
    	for(Integer n:numbers) {
    		System.out.println(n+" ");//输出7 3 5 1
    	}
    	
    }
}

这里创建了一个Integer数组,调用Util的静态泛型方法swap()交换两个元素的位置。

二、集合框架

1、框架介绍

        在编写面向对象的程序的时候,经常会遇到一些类型相同的对象,虽然可以用数组来存储这些对象,可是数组一经定义便不能改变大小。因此Java提供了一个集合框架来处理对象组,使得处理对象组更容易。

        集合是指用来集中存放一组对象的一个对象,相当于一个容器,提供了保存、获取和操作其他元素的方法。Java集合框架由两种类型构成,一个是Collection,另一个是Map。它们是最基本 的接口,其下还有子接口,简化图如下:

java 泛型集合参数 java泛型和集合_java

         Collection接口定义了集合操作的常用方法,基本可分为基本操作、批量操作、数组操作和流操作。特别要提的是集合类似于数组,因此也需要遍历,但是集合遍历一般用迭代器(Iterator)而不用循环。

 2、List接口及实现类

        List接口是Collection的子接口,实现一种线性表的子接口。存放在List中的元素都有下标,这个下标从0开始。List实现类包括ArrayList、LinkedList、Vector和Stack。List有E get(int index)(返回指定下标的元素)、E set(int index,E element)(修改指定下表处的元素)等常用方法。

1、ArrayList类

        ArrayList是最常用的线性表实现类,通过数组实现的集合对象,它实现了一个变长的对象数组,其元素可以动态的增加和删除。它有如下的构造方法:

ArrayList():创建一个空的数组线性表对象,默认初始长度为10。

ArrayList(Collection c):用集合c中的元素创建一个数组线性表对象。

ArrayList(int initialCapacity):创建一个空的数组线性表对象,并指定初始容量。

下面是有关ArrayList类用法操作的程序例子:

List<String> bigCities=new ArrayList<>();
bigCities.add("上海");
bigCities.add("北京");
bigCities.add("广州");
System.out.println(bigCities.size);
bigCities.add(1,"伦敦");
bigCities.set(2,"纽约");
System.out.println(bigCities.contains("上海"));
System.out.println(bigCities);
System.out.println(bigCities.indexOf("巴黎"));

2、迭代器

        Java迭代器是一种用于遍历集合类对象(如ArrayList、LinkedList、HashSet、HashMap等)中元素的工具。在Java中,所有的集合类都实现了接口java.util.Collection,而该接口中提供了一个Iterator方法,通过该方法可以返回一个迭代器对象。下面是Java中迭代器的使用方法:

1. 获取迭代器对象

使用集合类的iterator()方法获取迭代器对象,例如:

List<String> list = new ArrayList<>();
Iterator<String> it = list.iterator();

2. 遍历集合元素

使用while循环和hasNext()方法判断是否还有下一个元素,使用next()方法获取下一个元素,例如:

while(it.hasNext()) {
    String element = it.next();
    // do something with element
}

3. 删除集合元素

使用remove()方法删除集合中的元素,例如:
 

while(it.hasNext()) {
    String element = it.next();
    if(element.equals("foo")) {
        it.remove();
    }
}

        需要注意的是,不能在使用迭代器遍历集合的过程中直接使用集合的add()、remove()等方法修改集合,否则会导致ConcurrentModificationException异常,应该使用迭代器提供的remove()方法来删除元素。

3、双向迭代器

        双向迭代器(Bidirectional Iterator)是Java集合框架中的一种迭代器类型。它允许我们从集合的两个方向遍历元素。与单向迭代器(例如Iterator)不同,双向迭代器提供了向前迭代的能力。 

        在Java中,双向迭代器是Iterable接口的子接口之一,定义在java.util包中。它具有以下方法:

- next():返回列表中的下一个元素,并将迭代器位置向后移动一个元素。
- hasNext():如果列表中还有更多的元素并且迭代器没有到达末尾,则返回true。
- previous():返回列表中的前一个元素,并将迭代器位置向前移动一个元素。
- hasPrevious():如果列表中还有更多的元素并且迭代器没有到达开头,则返回true。
- remove():从列表中删除迭代器最后一个返回的元素。
- add():将指定的元素插入列表中。
- set():用指定的元素替换列表中最后一个返回的元素。

        在使用双向迭代器时需要注意的是,只有实现了List接口的集合才支持双向迭代器。因为List接口中定义了许多与索引相关的方法,这些方法可以用来实现双向迭代器的向前遍历操作。

4、Vector类和Stack类

        Vector类和Stack类都是Java中的集合类。Vector类是一种动态数组,可以根据需要自动增长和收缩。它与数组很像,但是可以自动调整大小,能够储存任何类型的数据。

        Stack类则是Vector类的子类,它实现了后进先出的栈数据结构。Stack类提供了push()方法将元素压入栈,pop()方法将栈顶元素弹出,并提供了查看栈顶元素的peek()方法。

        需要注意的是,由于Stack类是Vector类的子类,它所有的Vector类的方法和属性都可以使用。但是由于Stack类被设计为只用作栈的实现,因此建议只使用Stack类中提供的栈操作方法,并避免在Stack对象上使用Vector类中的其他方法来避免语义混淆。

3、Set接口以及实现类

        Java中的Set接口表示一组不允许重复元素的集合,并且不保证集合中元素的顺序。Set接口派生自Collection接口,因此它继承了Collection的许多方法,比如add()、remove()和size()等。

Java中的常用Set实现类有以下几种:

        1. HashSet:基于哈希表的Set实现类,不保证迭代顺序,但是可以快速查找元素,因此插入、删除和查找操作的时间复杂度为O(1)。

示例代码:

Set<String> set = new HashSet<>();

set.add("apple");
set.add("banana");
set.add("orange");

System.out.println(set); // 输出结果可能为[banana, orange, apple],顺序不定

        2. TreeSet:基于红黑树的Set实现类,能够自然排序(根据元素实现Comparable接口的compareTo()方法或提供的Comparator比较器),因此迭代时元素按照升序排列,插入、删除、查找操作的时间复杂度为O(log n)。

示例代码:

Set<Integer> set = new TreeSet<>();

set.add(4);
set.add(10);
set.add(2);

System.out.println(set); // 输出结果为[2, 4, 10]

        3. LinkedHashSet:基于哈希表和双向链表的Set实现类,维护插入顺序,因此迭代时元素按照插入顺序排列,插入、删除、查找操作的时间复杂度为O(1)。

示例代码:

Set<String> set = new LinkedHashSet<>();

set.add("apple");
set.add("banana");
set.add("orange");

System.out.println(set); // 输出结果为[apple, banana, orange]

        Set接口提供了许多用于操作集合的方法,比如add()、remove()、contains()、isEmpty()和size()等,使用时需要根据具体情况选择合适的Set实现类。

4、Queue接口及实现类和Deque接口

       队列(Queue)和双端队列(Deque)都是数据结构中用于存储数据元素的线性结构,它们最大的区别在于数据元素的出队方式。

        双端队列不仅支持队列的基本操作,还支持头部元素的出队、尾部元素的进队和出队。这意味着双端队列可以同时支持队列和栈的特性,因此可以用于更多的数据操作场景。

        Queue接口表示一种先进先出(FIFO)的数据结构。它提供了一系列方法,用于插入和删除元素,并可进行基本的检查操作。在Java中,Queue接口的实现类有很多,包括LinkedList、ArrayDeque等。

        LinkedList实现了Queue接口,并且还实现了List接口,因此它可以被用作队列和列表,它其中可以存储空值。LinkedList是基于链表实现的,因此在处理大量数据时可能会影响性能。ArrayDeque也实现了Queue接口,它是基于数组实现的双端队列,它其中不能存储空值。ArrayDeque在添加或删除元素时具有很高的性能,因为它支持队列和栈的操作。

        使用Queue接口和其实现类非常简单。首先,需要创建一个实例。例如,要创建一个LinkedList实例,可以使用以下代码:

Queue<String> queue = new LinkedList<>();

然后,可以使用Queue接口定义的方法来添加、删除和检查元素。例如,要向队列中添加一个元素,可以使用以下代码:

queue.offer("重庆");

要从队列中删除一个元素和检查队列是否为空:要,请使用以下代码:

String el = queue.poll();

5,Map接口及实现类

        Map接口是Java中的一种集合类型,用于存储键值对。它是一个抽象的接口,定义了一系列操作方法,例如添加、删除、查找、遍历等。

Map接口的常用实现类包括:

1. HashMap

2. TreeMap

3. Hashtable

常用方法有:

1. put(key, value):将键值对(key, value)插入到map中,如果key已经存在,则会覆盖之前的value值。

2. get(key):返回指定key对应的value值,如果key不存在,则返回null。

3. remove(key):删除指定key对应的键值对,并返回删除的value值,如果key不存在,则返回null。

4. containsKey(key):判断指定key是否存在于map中,存在返回true,否则返回false。

5. containsValue(value):判断指定value是否存在于map中,存在返回true,否则返回false。

6. size():返回map中键值对的个数。

7. clear():删除map中所有的键值对。

8. keySet():返回map中所有的key组成的set集合。

9. values():返回map中所有的value组成的collection集合。

10.isEmpty():返回映射是否为空。

11.putAll(Map<? extends K,? entends V> map):将参数map中的所有”键/值“添加到映射中。

等不同的方法。