实训笔记6.16

6.16

一、座右铭

我的故事你说,我的文字我落,我值几两你定,我去何方我挑。

二、知识回顾

2.1 Java泛型

2.1.1 泛型是用来提高代码效率,解决多态中向下转型的ClassCastException

2.1.2 泛型都是引用数据类型的,如果使用泛型的时候没有指定泛型的类型,泛型会当作Object类型来处理

2.1.3 泛型的声明语法和使用语法

  1. 类上的泛型

public class ClassName<T> {类中的任何一个位置去使用}

使用两种方式

1.1 创建类的对象的时候指定泛型的类型

ClassName<Integer> c = new ClassName<integer>();

ClassName<integer> c = new ClassName<>();

1.2 子类继承父类的时候去使用

class Son extends ClassName <integer>{}

1.3 带有泛型的类当作方法的形参或者返回值的时候也可以使用

public ClassName<Integer> demp(ClassName<Double> d){}

如果泛型当作方法的形参或者返回值时候,还是无法确定泛型的类型,那么我们也可以通过泛型的通配符、泛型上限和下限限制泛型的类型

  1. 方法上的泛型

使用场景

一个类中只有这个方法的返回值类型或者是形参列表不确定,那么我们按道理可以给类来声明泛型,然后让方法来使用,但是没必要……浪费,Java就专门为这种特殊情况提供了一个方法的泛型

public <T,V> T methodName (T t,V v) {}

使用:methodName(1,2)

  1. 接口上的泛型

tips:类上的的泛型和接口上的泛型不能使用在静态内容

三、Java集合体系

3.1 概念

Java集合和数组一样,都是存放一组相同类型数的容器,Java集合和数组的不同在于以下几点

  1. 虽然Java和数组都是存放一组相同类型的数据,但是数组是任何一种类型都可以存储,集合只能存放引用数据类型的数据(集合底层使用泛型来定义存储的数据类型)

  2. 数组有一个长度,长度一旦确定不可改变,Java集合容量没有限制-自动扩容的

【补充】StringBuffer、StringBuilder底层也可以自动扩容:借助Arrays.copyof(),底层又借助了System.arrayCopy()

3.2 集合分类-java.util

3.2.1 在Java当中,提供了各种各样的集合用来满足不同的业务需求

3.2.2单列集合——一条数据只有一列

所有的单列集合都是Collection接口的子类,Collection封装了很多单列集合共有的方法,只不过这些方法基本上都是抽象方法

Collection接口给我们提供的单列集合常用的方法

方法名 作用
size():int 获取集合存放的元素个数
isEmpty():boolean 判断集合是否为空集合
contains(Object):boolean 判断集合是否包含该元素
iterator():Iterator<E> 获取集合的迭代器,用于遍历集合
toArray():Object[] 将集合转换为数组
toArray(T[]):T[] 讲集合转换为指定类型的数组
add(E):boolean 将元素加到集合当中
remove(object) 移除某个元素
clear() 清空集合

代码示例

public class Demo {
    
    
	public static void main(String[] args) {
    
    
		Collection<Integer> col = new ArrayList<>();
		System.out.println(col.size());//0
		System.out.println(col.isEmpty());//true
		col.add(1);
		System.out.println(col.contains(1));//true
		col.add(2);
		/**
		 * 遍历集合:两种遍历方式
		 * 1、增强的for循环
		 * 2、迭代器也可以遍历: 获取迭代器 借助迭代器的hasNext判断有没有下一条数据 然后再借助next获取下一条数据
		 */
		for(Integer ele : col) {
    
    
			System.out.println(ele);//1
		}
		
		Iterator<Integer> iterator = col.iterator();
		while(iterator.hasNext()) {
    
    
			Integer next = iterator.next();
			System.out.println(next);//2 1 2
		}
		
		col.remove(1);
		System.out.println(col);//[2]
		col.clear();
		System.out.println(col);//[]
//		Object[] array = col.toArray();
//		System.out.println(Arrays.toString(array));//[]
//		Integer[] array = new Integer[col.size()];
//		col.toArray(array);
//		System.out.println(Arrays.toString(array));//[]	
	}
}

单列集合又细分为两种

  1. List接口类型的集合:List接口类型的集合:所有数据可以重复,而且是有序的–加入有序

    代码示例

    List<Integer> list = new ArrayList<>();
    		list.add(1);
    		list.set(0,1);
    		System.out.println(list);//[1]
    		
    		for (int i = 0; i < list.size(); i++) {
          
          
    			Integer integer = list.get(i);
    			System.out.println(integer);//1
    		}
    
    1. Vector:一般扩容为原先的2倍,如果有扩容因子,那么就是扩容为原先的长度+扩容因子

      List的实现类: list的实现类除了LinkedList增加了几个特殊方法以外,Vector和ArrayList基本没在接口之上再增加新的方法。

      Vector底层扩容的时候默认扩容为原先的一倍,但是如果扩容因子不为0的话,那么扩容为旧数组长度+扩容因子

      方法名 说明
      Vector<>(): 无参构造器底层调用this(10),
      底层先给你创建一个容量为10的数组存放元素,
      扩容因子也是0
      Vector(int initialCapacity): 有参构造器底层调用this(initialCapacity,0):
      底层给你创建一个指定长度的数组,
      顺序再指定一个扩容因子为0
      Vector(int initialCapacity,
      int capacityIncrement):
      底层创建一个指定长度的数组,
      指定数值的扩容因子

      代码示例

      		Vector<Integer> vec = new Vector<>();
      		vec.add(1);
      		vec.add(1,2);
      		vec.add(3);
      		vec.add(1);
      		System.out.println(vec);//[1, 2, 3, 1]
      
    2. ArrayList:一般扩容为原先的1.5倍

      ArrayList创建:ArrayList(): 底层会创建一个长度为10的数组存放数据,但是一定要注意,长度为10的数组并不是再构造器中直接创建的,而是再集合第一次增加元素的时候创建的

      1. ArrayList(int capacity)

      2. ArrayList(Collection)

    底层借助数组实现,数据可以重复,而且有序…加入有序

    代码示例

    		ArrayList<Integer> list = new ArrayList<>();
    		list.addAll(new ArrayList<Integer>(20));
    
    1. LinkedList:扩容是通过Node内部类完成

      LinkedList也是JavaList集合体系的一个实现类,只不过LinkedList底层不是借助数组来存储数据的而是借助双向链表去存储数据,而且通过双向链表维护数据的加入顺序。

      LinkedList因为使用双向链表来存储数据,在类中提前把链表的头部节点和尾部节点已经提前定义出来了,因此LinkedList在Collection、List接口之上提供了四个比较特殊的方法,可以直接对集合的头部节点和尾节点进行操作

      方法名
      addFirst(E)
      addLast(E)
      add(E)–默认在尾部增加数据
      removeFirst()
      removeLast()

      LinkedList一般用在频繁的修改和数据变更下。ArrayList更适合使用在频繁的数据查找下。

      底层借助双向链表来实现,数据可以重复,而且加入有序

      代码示例

    		LinkedList<Integer> list = new LinkedList<>();
    		list.add(1);
    
  2. set接口类型的集合:数据不允许重复,而且数据不一定有序

    Set集合也是一个单列集合,是Collection的子接口。

    Set接口集合体系没有提供任何的多余的方法,使用的集合增加数据方法都是Collection提供的

    Set接口集合虽然没有提供多余的方法,但是提供了存储数据的特性:元素不能重复

    Set集合判断两个元素是否重复借助Java的两个方法来完成的:

    方法名 说明
    hashCode 返回一个整数类型的值,默认返回的是这个对象在堆区的地址
    equals方法 比较两个对象是否值相等的,默认情况下比较两个对象的地址相等

    代码示例

    Set<Integer> set = new TreeSet<>();
    set.add(1);
    set.add(1);
    set.add(1);
    set.add(10);
    set.add(19);
    set.add(8);
    set.add(7);
    System.out.println(set);//[1, 7, 8, 10, 19]
    

    【注意】:在Java当中有要求的,如果两个对象通过equals返回比较为true的话,那么两个对象的hashCode方法必须返回相同的值。

    如果两个对象的hashCode值不一样那么两个对象一定不相等,如果两个对象的hashCode值一样的,不一定相等。

    判断规则:

    (1)set集合在添加元素时,先通过待添加元素的hashCode值和集合中的每一个元素的hashCode值做比较,如果hashCode值都不一样,那么认为元素 不重复 ,直接添加到集合当中了
    (2)如果hashCode值重复了,那么调用equals方法看返回结果,返回结果为true那么 重复 不添加如果返回结果为false那么就是 不重复 添加

    1. HashSet:不允许重复,元素是无序的

      代码示例

      Set<Student> set = new HashSet<>();
      Student stu = new Student("zs", 18, "s001");
      Student stu1 = new Student("zs", 18, "s001");
      set.add(stu);
      set.add(stu1);
      System.out.println(set);//[Student [name=zs, age=18, sno=s001]]
      
    2. LinkedHashSet:不允许重复,但是元素是有序的,加入有序

    3. TreeSet:不允许重复,但是元素有序的,大小有序,treeset集合中元素必须有比较器

      代码示例

      	Set<Student> set = new TreeSet<>(new Comparator<Student>() {
              
              
      			@Override
      			public int compare(Student o1, Student o2) {
              
              
      				if(o1.getAge()>o2.getAge()) {
              
              
      					return 1;
      				}else if(o1.getAge()<o2.getAge()) {
              
              
      					return -1;
      				}else {
              
              
      					return 0;
      				}
      			}
      		});
      		Student stu = new Student("zs", 18, "s001");
      		Student stu1 = new Student("ls", 20, "s002");
      		Student stu2 = new Student("ww", 15, "s003");
      		set.add(stu);
      		set.add(stu1);
      		set.add(stu2);
      		System.out.println(set);//[Student [name=ww, age=15, sno=s003], Student [name=zs, age=18, sno=s001], Student [name=ls, age=20, sno=s002]]
      

List接口、set接口:都是Collection接口的一个子接口

3.2.3 双列集合——一条数据有两列

所有的双列集合都是Map接口的子类

猜你喜欢

转载自blog.csdn.net/cai_4/article/details/131253109