java的知识点23——泛型Generics、Collection接口、List特点和常用方法、 ArrayList特点和底层实现

泛型Generics

一般通过“容器”来容纳和管理数据。程序中的“容器”就是用来容纳和管理数据。

数组就是一种容器,可以在其中放置对象基本类型数据

数组的优势:是一种简单的线性序列,可以快速地访问数组元素,效率高。如果从效率类型检查的角度讲,数组是最好的。

数组的劣势不灵活容量需要事先定义好,不能随着需求的变化而扩容。比如:在一个用户管理系统中,要把今天注册的所有用户取出来,那么这样的用户有多少个?在写程序时是无法确定的。因此,在这里就不能使用数组。

容器,也叫集合(Collection)

泛型:可以帮助我们建立类型安全的集合在使用了泛型的集合中,遍历时不必进行强制类型转换。JDK提供了支持泛型的编译器,将运行时的类型检查提前到了编译时执行,提高了代码可读性和安全性。

泛型的本质就是“数据类型的参数化”。可以把“泛型”理解为数据类型的一个占位符(形式参数),即告诉编译器,在调用泛型时必须传入实际类型。

未使用泛型时:

package cn.dym11;
//测试泛型
public class TestGeneric {
	public static void main(String[] args) {
		MyCollection mc=new MyCollection();
		mc.set("代止兮", 0);
		mc.set(8888, 1);
		Integer a=(Integer) mc.get(1);
		String b=(String) mc.get(0);
	}
}
class MyCollection {
	Object [] objs=new Object[5];
	public void set(Object obj,int index) {
		objs[index]=obj;
	}
	public Object get(int index) {
		return objs[index];
	}
}

使用泛型:

package cn.dym11;
//测试泛型
public class TestGeneric {
	public static void main(String[] args) {
		MyCollection<String> mc=new MyCollection<String>();
		mc.set("代止兮", 0);
		String b=mc.get(0);
	}
}
class MyCollection <E> {
	Object [] objs=new Object[5];
	public void set(E e,int index) {
		objs[index]=e;
	}
	public E get(int index) {
		return (E) objs[index];
	}
}

自定义泛型、容器中使用泛型

类的声明处增加泛型列表,如:<T,E,V>

public class Test {
    public static void main(String[] args) {
        // 以下代码中List、Set、Map、Iterator都是与容器相关的接口;
        List<String> list = new ArrayList<String>();
        Set<Man> mans = new HashSet<Man>();
        Map<Integer, Man> maps = new HashMap<Integer, Man>();
        Iterator<Man> iterator = mans.iterator();
    }
}

Collection、List、Set、Map、Iterator接口都定义了泛型。


Collection接口

Collection 表示一组对象,它是集中、收集的意思。Collection接口的两个子接口是ListSet接口。

注:由于List、Set是Collection的子接口,意味着所有List、Set的实现类都有上面的方法。

package cn.dym11;

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

//测试Collection接口中的方法
public class TestList {
	public static void main(String[] args) {
		Collection<String> c=new ArrayList<>();
		System.out.println(c.size());
		System.out.println(c.isEmpty());
		
		c.add("代止兮");
		c.add("苍凌");
		System.out.println(c);
		System.out.println(c.size());
		
		System.out.println(c.contains("苍凌"));
		
		Object[] objs=c.toArray();
		System.out.println(objs);
		
		c.remove("苍凌");
		System.out.println(c);
		
		c.clear();
		System.out.println(c.size());
	}
	
}

package cn.dym11;

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

//测试Collection接口中的方法
public class TestList {
	public static void main(String[] args) {
		test02();
	}
	public static void test02() {
		
		List<String> list01=new ArrayList <>();
		list01.add("aa");
		list01.add("bb");
		list01.add("cc");
		
		List<String> list02=new ArrayList <>();
		list02.add("aa");
		list02.add("dd");
		list02.add("ee");
		
		System.out.println("list01:"+list01);  //list01:[aa, bb, cc]
		
		// list01.addAll(list02);
		// System.out.println("list01:"+list01);  //list01:[aa, bb, cc, aa, dd, ee]
		
		// list01.removeAll(list02);
		// System.out.println("list01:"+list01);  //list01:[bb, cc]
		
		list01.retainAll(list02);
		System.out.println("list01:"+list01); // list01:[aa]
		
		System.out.println(list01.containsAll(list02));
	}
}


List特点和常用方法

List是有序、可重复的容器 

有序:List中每个元素都有索引标记。

可重复:List允许加入重复的元素。更确切地讲,List通常允许满足 e1.equals(e2) 的元素重复加入容器。

List接口常用的实现类有3个:ArrayListLinkedListVector

List中操作索引的常用方法

package cn.dym11;

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

public class TsetList01 {
    public static void main(String[] args) {
    	test01();
    }
    public static void test01(){
    	List<String> list=new ArrayList<>();
    	list.add("A");
    	list.add("B");
    	list.add("C");
    	list.add("D");
    	
    	System.out.println(list);
    	
    	list.add(2,"代止兮");
    	System.out.println(list);
    	
    	list.remove(2);
    	System.out.println(list);
    	
    	list.set(2, "代止兮");
    	System.out.println(list);
    	
    	System.out.println(list.get(2));
    	
    	list.add("C");
    	list.add("B");
    	list.add("A");
    	System.out.println(list);
    	System.out.println(list.indexOf("B"));  //找到,返回索引位置
    	System.out.println(list.indexOf("d"));  //找不到,返回-1
    	System.out.println(list.lastIndexOf("B"));
    }
}


 ArrayList特点和底层实现

ArrayList底层是用数组实现的存储。   特点:查询效率高,增删效率低,线程不安全。

ArrayList底层使用Object数组来存储元素数据

数组长度是有限的,而ArrayList是可以存放任意数量的对象,长度不受限制,那么它是怎么实现的呢?本质上就是通过定义新的更大的数组,将旧数组中的内容拷贝到新数组,来实现扩容。

自定义实现一个ArrayList,体会底层原理

第一个版本:

package cn.dym11;

// 自定义实现一个ArrayList,体会底层原理

public class SxtArrayList {
    private Object[] elementData;
    private int size;
    
    private static final int DEFAULT_CAPACITY=10;
    
    public SxtArrayList() {
    	elementData=new Object[DEFAULT_CAPACITY];
    }
    
    public SxtArrayList(int capacity) {
    	elementData=new Object[capacity];
    }
    
    public void add(Object obj) {
    	elementData[size++]=obj;
    }
    
    public String toString() {
    	StringBuilder sb=new StringBuilder();
    	// [a,b,c]
    	sb.append("[");
//    	for(Object obj:elementData) {
//    		sb.append(obj);
//    	}
//    	sb.append("]");
    	
    	for(int i=0;i<size;i++) {
    		sb.append(elementData[i]+",");
    	}
    	sb.setCharAt(sb.length()-1, ']');
    	
    	return sb.toString();
    }
    
    public static void main(String[] args) {
    	SxtArrayList s1=new SxtArrayList(20);
    	s1.add("aa");
    	s1.add("bb");
    	
    	System.out.println(s1);
    }
}

//增加泛型
//增加数组扩容

package cn.dym11;

// 自定义实现一个ArrayList,体会底层原理
//增加泛型
//增加数组扩容
public class SxtArrayList02<E> {
    private Object[] elementData;
    private int size;
    
    private static final int DEFAULT_CAPACITY=10;
    
    public SxtArrayList02() {
    	elementData=new Object[DEFAULT_CAPACITY];
    }
    
    public SxtArrayList02(int capacity) {
    	elementData=new Object[capacity];
    }
    
    public void add(E element) {
    	// 什么时候扩容??
    	if(size==elementData.length) {
    		//怎么扩容?? //扩容操作
    		Object[] newArray=new Object[elementData.length+(elementData.length>>1)];
    		System.arraycopy(elementData, 0, newArray, 0,elementData.length );
    		elementData=newArray;
    	}	
    	elementData[size++]=element;
    }
    
    public String toString() {
    	StringBuilder sb=new StringBuilder();
    	// [a,b,c]
    	sb.append("[");
//    	for(Object obj:elementData) {
//    		sb.append(obj);
//    	}
//    	sb.append("]");
    	
    	for(int i=0;i<size;i++) {
    		sb.append(elementData[i]+",");
    	}
    	sb.setCharAt(sb.length()-1, ']');
    	
    	return sb.toString();
    }
    
    public static void main(String[] args) {
    	SxtArrayList02 s1=new SxtArrayList02(20);
    	for(int i=0;i<40;i++) {
    		s1.add("dym"+i);
    	}
    	
    	System.out.println(s1);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_39368007/article/details/84536609