Java类集(1)

1 Java类集简介

1.1 Java类集

        类集实际上就属于动态对象数组,在实际开发之中,数组的使用出现的几率并不高,因为数组本身有一个最大的缺 陷:数组长度是固定的。由于此问题的存在,从JDK1.2开始,Java为了解决这种数组长度问题,提供了动态的对象数 组实现框架–Java类集框架。Java集合类框架实际上就是java针对于数据结构的一种实现。而在数据结构之中,最为 基础的就是链表。
下面看下链表的特点:

  • 节点关系的处理操作,核心需要一个Node类(保存数据,设置引用)。
  • 在进行链表数据的查找、删除的时候需要equals()方法支持。
    实际上之前链表的实现就是参考Java集合类实现的。

1.2 Collection集合接口

        在Java的类集里面(java.util包)提供了两个最为核心的接口:Collection、Map接口。其中Collection接口的操作形式与之 前编写链表的操作形式类似,每一次进行数据操作的时候只能够对单个对象进行处理。
        Collection是单个集合保存的最大父接口。
        Collection接口的定义如下:

public interface Collection<E> extends Iterable<E>

        从JDK1.5开始发现Collection接口上追加有泛型应用,这样的直接好处就是可以避免ClassCastException,里面的所有 数据的保存类型应该是相同的。在JDK1.5之前Iterable接口中的iterator()方法是直接在Collection接口中定义的。此接 口的常用方法有如下几个:
在这里插入图片描述
        在开发之中如果按照使用频率来讲:add()、iterator()方法用到的最多。需要说明的一点是,我们很少会直接使用 Collection接口,Collection接口只是一个存储数据的标准,并不能区分存储类型。例如:要存放的数据需要区分重 复与不重复。在实际开发之中,往往会考虑使用Collection接口的子接口:List(允许数据重复)、Set(不允许数据重 复)。
        以上接口的继承、使用关系如下:
在这里插入图片描述
Collection接口中有两个重要方法:add()、iterator()。子接口都有这两个方法。

2 List接口

2.1 List接口概述

        在实际开发之中,List接口的使用频率可以达到Collection系列的80%。在进行集合处理的时候,优先考虑List接口。
        首先来观察List接口中提供的方法,在这个接口中有两个重要的扩充方法 :
在这里插入图片描述
List子接口与Collection接口相比最大的特点在于其有一个get()方法,可以根据索引取得内容。由于List本身还是接 口,要想取得接口的实例化对象,就必须有子类,在List接口下有三个常用子类:ArrayList、Vector、LinkedList。
在这里插入图片描述
最终的操作还是以接口为主,所以所有的方法只参考接口中定义的方法即可。

2.2 ArrayList子类(优先考虑)

ArrayList是一个针对于List接口的数组实现。下面首先利用ArrayList进行List的基本操作。
范例:观察List基本处理。

import java.util.ArrayList; 
import java.util.List;
 
public class TestDemo {    
	public static void main(String[] args) {        
		// 此时集合里面只保存String类型        
		List<String> list = new ArrayList<>() ;        
		list.add("Hello") ;        
		// 重复数据        
		list.add("Hello") ;        
		list.add("Bit") ;        
		System.out.println(list) ;    
	} 
}

通过上述代码我们可以发现,List允许保存重复数据。
范例:观察其他操作

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

public class TestDemo {    
	public static void main(String[] args) {        
		// 此时集合里面只保存String类型        
		List<String> list = new ArrayList<>() ;        
		System.out.println(list.size()+"、" + list.isEmpty());        
		list.add("Hello") ;        
		// 重复数据       
		list.add("Hello") ;        
		list.add("Bit") ;        
		System.out.println(list.size()+"、" + list.isEmpty());
		System.out.println(list) ;        
		System.out.println(list.remove("Hello")) ;       
		System.out.println(list.contains("ABC")) ;        	
		System.out.println(list.contains("Bit")) ;        
		System.out.println(list);    
	}
} 

List本身有一个好的支持:存在get()方法,可以利用get()方法结合索引取得数据。
范例:List的get()操作

import java.util.ArrayList; 
import java.util.List;
 
public class TestDemo {    
	public static void main(String[] args) {        
		// 此时集合里面只保存String类型        
		List<String> list = new ArrayList<>() ;        
		list.add("Hello") ;        
		// 重复数据        
		list.add("Hello") ;        
		list.add("Bit") ;        
		for (int i = 0; i < list.size() ; i++) {            
			System.out.println(list.get(i)) ;        
		}    
	} 
}

get()方法是List子接口提供的。如果现在操作的是Collection接口,那么对于此时的数据取出只能够将集合变为对象 数组操作。
范例:通过Collection进行输出处理。

import java.util.ArrayList; 
import java.util.Arrays; 
import java.util.Collection;
 
public class TestDemo {   
	public static void main(String[] args) {        
		// 此时集合里面只保存String类型
		Collection<String> list = new ArrayList<>() ;        
		list.add("Hello") ;        
		// 重复数据        
		list.add("Hello") ;        
		list.add("Bit") ;        
		// 操作以Object为主,有可能需要向下转型,就有可能产生ClassCastException        
		Object[] result = list.toArray() ;        
		System.out.println(Arrays.toString(result)) ;    
	} 
}

注意:开发中尽量不要使用Collection接口

2.3 集合与简单Java类

在实际开发中,集合里面保存最多的数据类型,就是简单Java类。
范例:向集合保存简单Java类对象。

import java.util.ArrayList; 
import java.util.List; 
import java.util.Objects;
 
class Person {    
	private String name ;    
	private Integer age ;
 
    public Person(String name, Integer age) {        
    	this.name = name;        this.age = age;    
    }
 
    @Override    
    public String toString() {        
    	return "Person{" +                "name='" + name + '\'' +                ", age=" + age +                '}';    
    }
 
    @Override    
    public boolean equals(Object o) {        
    if (this == o) return true;        
    if (o == null || getClass() != o.getClass()) return false;        
    Person person = (Person) o;        
    return Objects.equals(name, person.name) &&                
    	Objects.equals(age, person.age);    
    }    
    public String getName() {        
    	return name;    
    }
 
    public void setName(String name) {        
    	this.name = name;
    	 }
 
    public Integer getAge() {        
    	return age;    
    }
 
    public void setAge(Integer age) {        
    	this.age = age;    
    } 
} 

public class TestDemo {    
	public static void main(String[] args) {        
		List<Person> personList = new ArrayList<>() ;        
		personList.add(new Person("张三",10)) ;        
		personList.add(new Person("李四",11)) ;        
		personList.add(new Person("王五",12)) ;        
		// 集合类中contains()、remove()方法需要equals()支持        
		personList.remove(new Person("李四",11)) ;        
		System.out.println( personList.contains(new Person("王五",12)));        
		for (Person p: personList) {            
			System.out.println(p) ;        
		}    
	} 
}

集合操作简单java类时,对于remove()、contains()方法需要equals()方法支持。

2.4 旧的子类(Vector) (使用较少)

Vector是从JDK1.0提出的,而ArrayList是从JDK1.2提出的。
范例:使用Vector

import java.util.List; 
import java.util.Vector;
 
public class TestDemo {    
	public static void main(String[] args) {        
		List<String> list = new Vector<>() ;        
		list.add("hello") ;        
		list.add("hello") ;        
		list.add("bit") ;        
		System.out.println(list) ;        
		list.remove("hello") ;        
		System.out.println(list) ;    
	} 
}

面试题:请解释ArrayList与Vector区别

  1. 历史时间:ArrayList是从JDK1.2提供的,而Vector是从JDK1.0就提供了。
  2. 处理形式:ArrayList是异步处理,性能更高;Vector是同步处理,性能较低。
  3. 数据安全:ArrayList是非线程安全;Vector是性能安全。
  4. 输出形式:ArrayList支持Iterator、ListIterator、foreach;Vector支持Iterator、ListIterator、foreach、 Enumeration。

        在以后使用的时候优先考虑ArrayList,因为其性能更高,实际开发时很多时候也是每个线程拥有自己独立的集合资 源。如果需要考虑同步也可以使用concurrent包提供的工具将ArrayList变为线程安全的集合(了解)。

2.5 linkedList子类

在List接口中还有一个LinkedList子类,这个子类如果向父接口转型的话,使用形式与之前没有任何区别。
范例:使用LinkedList

import java.util.LinkedList; 
import java.util.List;
 
public class TestDemo {    
	public static void main(String[] args) {        
		List<String> list = new LinkedList<>() ;        
		list.add("hello") ;        
		list.add("hello") ;        
		list.add("bit") ;        
		System.out.println(list) ;        
		list.remove("hello") ;        
		System.out.println(list) ;
	} 
}

面试题:请解释ArrayList与LinkedList区别

  • 观察ArrayList源码,可以发现ArrayList里面存放的是一个数组,如果实例化此类对象时传入了数组大小,则 里面保存的数组就会开辟一个定长的数组,但是后面再进行数据保存的时候发现数组个数不够了会进行数 组动态扩充。 所以在实际开发之中,使用ArrayList最好的做法就是设置初始化大小。
  • LinkedList:是一个纯粹的链表实现,与之前编写的链表程序的实现基本一样(人家性能高)。
    总结:ArrayList封装的是数组;LinkedList封装的是链表。ArrayList时间复杂度为1,而LinkedList的复杂度为n。
发布了91 篇原创文章 · 获赞 193 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_44057443/article/details/100068695