Java零基础(十五)之集合

1.集合的概念
概念:对象的容器,集合中提供了常用的方法,可以实现与数组类似的存储

与数组的区别:
数组长度固定,集合是动态存储的
数组可以存基本类型和引用类型,集合只能存引用类型

集合框架介绍:
在这里插入图片描述

1.1 Collection接口
Collection: 集合的根接口
包含了两个子接口: 1. List 2.Set

//Collection的常用方法:
public class Test1 {
    
    
	public static void main(String[] args) {
    
    
		Collection co = new ArrayList();
		co.add(1);  //添加元素   Integer-自动装箱
		co.add(3);  //集合只能存对象?
		co.add(2.5);    //Double
		System.out.println(co.contains(1));  //true
		System.out.println(co.remove(1));    //删除单个对象
		
		System.out.println(co.size());  //求长度
		
		Collection co2 = new ArrayList();
		co2.add(5);  
		co2.add(7);
		System.out.println(co.addAll(co2));  //添加一个集合
		
		System.out.println(co);
		/*
		co.clear();
		System.out.println(co.isEmpty());  //true
		System.out.println(co);  //[]  不是null
		*/
		
		Object[] as = co.toArray();   //转数组
		System.out.println(Arrays.toString(as));
		
	}
}

1.2. List接口
List接口,是Collection的子接口
包含了两个重要的实现类: ArrayList,LinkedList其中还有一个不太常用实现类Vector
List的特点:存储的元素有序(有序!=排序),可重复

public class Test1 {
    
    
	public static void main(String[] args) {
    
    
		List list = new ArrayList();
		list.add(1);
		list.add(3);
		list.add(2);
		list.add(3);
		list.add(2, 6);
		System.out.println(list); //1,3,6,2,3
		System.out.println(list.get(2));  //根据下标获取元素
		
		//循环遍历
		for(int i=0;i<list.size();i++) {
    
    
			System.out.print(list.get(i)+"\t");  //获取循环遍历的元素
		}
		System.out.println();
		
		//增强for
		for(Object o :list) {
    
     //将集合的元素,挨个取出来
			System.out.print(o+"\t");
		}
		System.out.println();
		
		//迭代器:
		Iterator it = list.iterator();
		while(it.hasNext()) {
    
     //循环判断是否有下一个
			System.out.println(it.next()); //取出来后,指向下一个
		}
		
	}
}

1.3. Vector实现类

Vector与ArrayList的区别
Vector是加了锁,安全,性能低
ArrayList没有加锁,不安全,性能高(重点)

//Vector提供了一些自身独有的方法:

public class VectorTest {
    
    
	public static void main(String[] args) {
    
    
		Vector vector = new Vector();
		/*
		vector.add(1);
		vector.add(3);
		vector.add(2);
		vector.add(3);
		System.out.println(vector);
		*/
		
		//vector独有的方法
		vector.addElement(1);
		vector.addElement(3);
		vector.addElement(2);
		
		System.out.println(vector);
		//循环遍历与ArrayList类似,有基本for,有迭代器,还有自身独有的遍历
		Enumeration enu = vector.elements();  //通过枚举器遍历
		while(enu.hasMoreElements()) {
    
     //判断是否有元素
			System.out.println(enu.nextElement());  //如果有则取出来,指向下一个
		}
	}
}


1.4. ArrayList实现类

LinkedList的操作:
与ArrayList的操作完全一致,只是存储原理不同
ArrayList的存储原理:通过数组扩容的方式存储
分析方式:
1.画图分析原理 2.分析源码(找主线)

//LinkedList的存储原理:通过双向链表存储
//分析方式:
//1.画图分析原理     2.分析源码(找主线)
public class ArrayListTest {
    
    
	public static void main(String[] args) {
    
    
		List list = new ArrayList();
		list.add(1);
		list.add(3);
		list.add(1);
		list.add(2);
		System.out.println(list);
	}
}

ArrayList存储原理分析

在这里插入图片描述
在这里插入图片描述

LinkedList存储原理分析

在这里插入图片描述在这里插入图片描述

ArrayList与LinkedList性能PK
分析增删改查:

  1. 向后追加:相差不大,ArrayList稍快
  2. 指定位置的删除和添加
    ArrayList集体搬迁 PK LinkedList定位==》LinkedList稍快,
    如果连续指定位置增删,LinkedList快很多
  3. 修改和查找
    ArrayList快

结论:后续项目中,经常使用ArrayList,因为常用的操作是定位和向后追加

public class ArrayListTest2 {
    
    
	public static void main(String[] args) {
    
    
		List list = new LinkedList();
		long start = System.currentTimeMillis();
		for(int i=0;i<10000;i++) {
    
    
			list.add(i);
		}
		System.out.println(System.currentTimeMillis()-start);
	}
}


  1. 泛型

2.1 泛型应用

//案例: 通过List存储自定义对象
class Person{
    
    
	String name;
	
	public Person(String name) {
    
    
		this.name = name;
	}

	
}
public class Test1 {
    
    
	public static void main(String[] args) {
    
    
		//问题1:警告太多,清理黄线  2.假设存其他引用类型,编译是通过的,运行时报错
		//报错提示:类型转换异常
		//解决方案:从源头上规避问题,存值前约束所存储的类型为Person类型--泛型
		List<Person> list = new ArrayList<>();
		list.add(new Person("凤姐"));
		list.add(new Person("芙蓉"));
		list.add(new Person("刘亦菲"));
		//list.add("高圆圆");  //从源头上规避了其他类型的值的存储
		
		//循环遍历,获取对象的属性
		Iterator<Person> it = list.iterator();
		while(it.hasNext()) {
    
    
			//ClassCastException: String cannot be cast to Person
			Person person = it.next(); //有了泛型约束,无需强转
			System.out.println(person.name);
		}
	}
}

2.2 泛型定义
概述: 参数化类型,把类型作为参数传递,约束了所存储值的类型

//常见的泛型分类:
//泛型类(常用)      泛型接口(常用)       泛型方法
//语法: <T>

//泛型类:  MyFan <T>: 约束泛型类中所有使用泛型参数的方法所传的类型
class MyFan <T>{
    
    
	public void add(T t) {
    
    
		System.out.println(t);
	}
}

//泛型接口:FanInter<T>:约束泛型中接口传递类型,泛型接口实现类也需要定义泛型
interface FanInter<T>{
    
    
	void test(T t);
}
//实现类实现泛型接口
class MyImpl<T> implements FanInter<T>{
    
    

	@Override
	public void test(T t) {
    
    
		
	}
	
	//泛型方法,泛型的约束只能用在该方法中(不常用)
	public <E> void show(E e) {
    
    
		System.out.println("泛型方法:"+e);
	}
	
}
public class Test2 {
    
    
	public static void main(String[] args) {
    
    
		MyFan<Integer> fan = new MyFan();
		fan.add(6);
	}
}

2.3 自定义泛型集合

//自定义泛型集合:  泛型接口与实现类组合使用
//泛型好处: 规范化所使用的类型    获取本身类型是无需强转,提高安全性
interface MyList<E>{
    
      //泛型接口
	public void add(E e);
}

class MyArrayList<E> implements MyList<E>{
    
    

	@Override
	public void add(E e) {
    
    
		System.out.println("集合存储:"+e);
	}
	
}

public class Test3 {
    
    
	public static void main(String[] args) {
    
    
		MyList<Integer> list = new MyArrayList<>();
		list.add(666);
          
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_45682261/article/details/125146131
今日推荐