javaSE基础——集合全面解析笔记

javaSE基础——集合全面解析笔记

  • 英文单词
  • 一、容器定义
    • 1.1、容器继承体系
  • 二、Set--------容器类
    • 部分方法数学集合意义
    • 2.1 HashSet
      • 2.1.1 基本用法
      • 2.1.2 特点
      • 2.1.3 练习——使用HashSet解决
      • 2.1.4 面试题
    • 2.2 TreeSet
      • 2.2.1 基本用法
      • 2.2.2 特点
      • 2.2.3 面试题
    • 2.3 自然排序
      • 2.3.1 比较器---comparator
      • 2.3.2 面试题
    • 2.4 自定义二叉树结构
    • 2.5 HashMap
      • 2.5.1 底层原理
        • JDK1.7
        • JDK1.8
      • 2.5.2 基本用法
      • 2.5.3 特点
      • 2.5.4 面试题
  • 三、List--------有序列表
    • 3.1 Vector--------==不建议使用==
    • 3.2 ArrayList
      • 3.2.1 基本用法
      • 3.2.2 特点
    • 3.3 LinkedList
      • 3.2.1 基本用法
      • 3.3.2 特点
      • 3.3.3 嵌套练习
    • 3.4 Stack 栈结构
  • 未完待续

英文单词

一、容器定义

可以简单理解为一个装东西的盒子或箱子,是用于存放元素的一种结构,包括变量,数组,对象,容器类详解见下文

1.1、容器继承体系

Collection接口是所有容器的根层次接口,表示所有容器类的标准。
是否实现Collection接口是容器的判断条件。

二、Set--------容器类

public interface Set<E> extends Collection<E>

表示泛型,用于定义容器中存放的元素的类型,一般指代引用数据类型
基本数据类型不能当作泛型来使用,需要使用基本数据类型的封装类
set的特点:不能存在重复的元素(hashcode相同的元素为重复元素)

部分方法数学集合意义

  1. addAll--------------添加————并集
  2. containsAll()------包含检查——子集
  3. removeAll()-------删除————差集
  4. retainAll()---------保留————交集

2.1 HashSet

public class HashSet<E> extends AbstractSet<E> implements Set<E>, Cloneable, Serializable

2.1.1 基本用法

	hs.add(E o);/*添加元素*/								(boolean)
	hs.clear();/*移除所有元素*/							(void)
	hs.clone();/*浅表复制,并没有克隆*/					(object)
	hs.contains(Object o);/*不包含o元素时返回true*/		(boolean)
	hs.isEmpty();/*没有元素时返回true*/					(boolean)
	hs.iterator();/*返回迭代器*/							(iterator<E>)
	hs.remove(Object o);/*移除o元素*/					(boolean)
	hs.size();/*返回容量长度*/							(int)

hs.contains(Object o);//不包含o元素时返回true (boolean)

package com.sjh.Set;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

public class HashSetTest1 {

	public static void main(String[] args) {
		Set<String> hs = new HashSet<String>();
		//添加元素
		hs.add("123");
		hs.add("456");
		hs.add("qaa");
		hs.add("xxx");
		hs.add("123");//不生效
		hs.add(null);

		//获取
		//for-each循环
		System.out.println("for-each循环");
		for(String sbrt : hs){
			System.out.println(sbrt);
		}
		//或者使用迭代器
		System.out.println("迭代器");
		Iterator<String> it = hs.iterator();
		while(it.hasNext()){
			String str = it.next();
			System.out.println(str);
		}
		
		//remove移除
		hs.remove("123");
		System.out.println(hs);
	}
}

输出结果

for-each循环
qaa
null
123
456
xxx
迭代器
qaa
null
123
456
xxx
[qaa, null, 456, xxx]

2.1.2 特点

1.不能存放重复元素
2.底层代码结构是哈希表(HashTable)
3.无序----无索引
4.可以存放null元素
5.牺牲空间换时间(桶)----运行速度较快
6.初始容量16和加载因子0.75,根据底层hashMap实例决定
7.实现不同步,线程不安全

2.1.3 练习——使用HashSet解决

String score[] s ={
“A,语文,98”,
“B,数学,87”,
“B,英语,56”,
“C,语文,66”,
“G,数学,90”};
name[A B C D E F G]
问:谁没有参加考试

package com.sjh.Set;

import java.util.HashSet;
import java.util.Set;

public class HashSetTest2 {
	public static void main(String[] args) {
		String[] score={
		"A,语文,98",
		"B,数学,87",
		"B,英语,56",
		"C,语文,66",
		"G,数学,90"};
		String[] name={"A","B","C","D","E","F","G"};
		
		Set<String> scoreSet=new HashSet<String>();
		for (int i = 0; i < score.length; i++) {
			//以逗号为界拆分score并暂时存放在bRet中
			//bRet[0]=A,bRet[1]=语文,bRet[2]=98
			String[] bRet = score[i].split(",");
			//把bRet[0]添加到scoreSet中
			scoreSet.add(bRet[0]);
		}
		System.out.println(scoreSet);
		
		Set<String> nameSet=new HashSet<String>();
		for (int i = 0; i < name.length; i++) {
			nameSet.add(name[i]);
		}
		System.out.println(nameSet);
		
		//数学差集
		nameSet.removeAll(scoreSet);
		System.out.println(nameSet);
	}
}

输出结果

[A, B, C, G]
[A, B, C, D, E, F, G]
[D, E, F]

2.1.4 面试题

问:HashSet是否是HashMap的实例?
答:是,虽然两个容器实现的是不同的接口,但是底层都是哈希表(HashTable)

问:什么是重复元素?
重复元素的哈希值(hashcode)一定相同,一定在同一个桶内
哈希值(hashcode)相同的元素不一定是重复元素,桶内不只有一个类,还需要使用equals(java.lang.Object)方法确定

2.2 TreeSet

2.2.1 基本用法

	ts.add(E o);/*添加元素*/								(boolean)
	ts.clear();/*移除所有元素*/							(void)
	ts.clone();/*浅表复制,并没有克隆*/					(object)
	ts.contains(Object o);/*包含o元素时返回true*/			(boolean)
	ts.isEmpty();/*没有元素时返回true*/					(boolean)
	ts.iterator();/*返回迭代器*/							(iterator<E>)
	ts.remove(Object o);/*移除o元素*/					(boolean)
	ts.size();/*返回容量长度*/							(int)

ts.contains(Object o);//包含o元素时返回true (boolean)

    ts.first();/*返回已排序set中第一个(最小)元素*/			(E)
    ts.last();/*返回已排序set中最后一个(最大)元素*/			(E)
	//返回用于确定已排序set顺序的比较器,或者,如果此树set使用其元素的自然顺序,则返回 null
	ts.comparator();									(Comparator<? super E>)
    //返回此set的部分视图,要求其元素严格小于 toElement
    ts.headSet(E toElement);							(SortedSet<E>)
    //返回此set的部分视图,其元素从fromElement(包括)到toElement(不包括)
    ts.subSet(E fromElement, E toElement);				(SortedSet<E>) 
    //返回set的部分视图,其元素大于或等于fromElement
    ts.tailSet(E fromElement);							(SortedSet<E>)
package com.sjh.Set;

import java.util.Set;
import java.util.TreeSet;
import java.util.Iterator;

public class TreeSetTest1 {
	
	public static void main(String[] args) {
		Set<Integer> ts = new TreeSet<Integer>();
		
		ts.add(7);
		ts.add(0);
		ts.add(2);
		ts.add(3);
		ts.add(0);//不生效
		//ts.add(null);//不能存放null,报java.lang.NullPointerException异常
		
		//获取
		//for-each循环 
		for(Integer sbrt : ts){
			System.out.println(sbrt);
		}
		//或者使用迭代器
		Iterator<Integer> it = ts.iterator();
		while(it.hasNext()){
			Integer str = it.next();
			System.out.println(str);
		}
		
		//remove移除
		ts.remove(0);
		System.out.println(ts);		
	}
}

输出结果

for-each循环
0
2
3
7
迭代器
0
2
3
7
[2, 3, 7]

2.2.2 特点

1.不能存放重复元素
2.底层结构是二叉树结构
3.二叉树认为能够存放在树形结构中的元素都是有序元素
4.实现不同步,线程不安全

2.2.3 面试题

问:HashSet和TreeSet的异同?
同:不能存放重复元素,实现不同步,线程不安全

HashSet底层代码结构是哈希表(HashTable),无序,可以存放null
TreeSet底层代码结构是二叉树,有序,不能存放null

2.3 自然排序

实体类实现Comparable接口 ,该实体类就存在自然排序的功能

package com.sjh.Set;

public class Person implements Comparable<Object>{
	
	private String name;
	private int age;
	
	//构造方法
	public Person() {
		// TODO Auto-generated constructor stub
	}
	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	
	//get和set方法
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}

	@Override//重写toString方法
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}

	@Override//重写compareTo方法
	public int compareTo(Object o) {
		//instanceof------检查Object o是否是Person类型
		if (!(o instanceof Person))
			return -1;
		Person p = (Person) o;//强制转换
		
		return this.getName().compareTo(p.getName());
	}
}

2.3.1 比较器—comparator

	//根据元素的自然顺序 对指定列表按升序进行排序
	Collections.sort(List<T> list)								(static <T extends Comparable<? super T>> void)   
	//根据指定比较器产生的顺序对指定列表进行排序
	Collections.sort(List<T> list, Comparator<? super T> c)		(static <T> void )
          
package com.sjh.Set;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class TreeSetTest2 {
	
	public static void main(String[] args) {
		
		List<Person> set = new ArrayList<Person>();
		
		set.add(new Person("zhangsan",18));
		set.add(new Person("lisi",27));
		set.add(new Person("wangwu",21));
		
		//Comparable自然排序
		Collections.sort(set);
		System.out.println(set);
		
		//Comparator自定义排序
		Collections.sort(set, new Comparator<Person>(){

			@Override//重写compare方法
			public int compare(Person o1, Person o2) {
				return o1.getAge()-o2.getAge();//小于返回-1,等于返回0,大于返回1
			}
		}
		);
		
		System.out.println(set);		
	}
}

输出结果

[Person [name=lisi, age=27], Person [name=wangwu, age=21], Person [name=zhangsan, age=18]]
[Person [name=zhangsan, age=18], Person [name=wangwu, age=21], Person [name=lisi, age=27]]

2.3.2 面试题

问:Collection和Collections的区别?
Collection是容器类的根接口,用于描述一个类是否是容器,里面实现了增删改查方法
Collections是Collection的工具类,主要用于集合的排序,反转,线程安全等

问:Comparable和Comparator的异同?
同:小于返回负整数,等于返回0,大于返回正整数
public interface Comparable,java.lang.Comparable,需要重写compareTo(T o)方法,排序逻辑在待排序对象的类中,内部比较器,修改时需要改变对象类本身,耦合性高。自然排序,可以和自己比较,具体依赖compareTo方法的实现。

public interface Comparator,java.util.Comparator,需要重写compare(T o1,T o2)方法,排序逻辑在另一个类中,外部比较器,修改时不需要改变对象类本身,耦合性低。不满意自然排序时可以自定义排序逻辑和标准,可选重写equals(Object obj)方法

2.4 自定义二叉树结构

package com.sjh.CustomBinaryTree;

public class Node {

	public int data;		//数据
	public Node leftNode;	//左节点
	public Node rightNode;	//右节点
	
	/**
	 * 添加节点 
	 * @param t
	 */
	public void addNode(Node p){		//p为包括1个根节点,1个左节点和1个右节点在内的一个二叉树
										//data是p这个树的根节点的值
		
		if(p.data<this.data){			//比根节点小,p嫁接在根树左节点上
			if(leftNode == null)		//左节点为空时,p成为左节点
				 leftNode = p;
			else
				 leftNode.addNode(p);	//把左节点作为根节点添加节点,递归循环
		}else{							//比根节点大,p嫁接在根树右节点上
			if(rightNode == null)		//右节点为空时,p成为右节点
				 rightNode = p;
			else
				rightNode.addNode(p);	//把右节点作为根节点添加节点,递归循环
		}
	}
	
	/**前序递归遍历
	 * Preorder Recursion Traversal (VLR)
	 */
	public void VLRrSort(){
		
		System.out.print(data+" ");
		if(leftNode!=null) leftNode.VLRrSort();
		if(rightNode!=null) rightNode.VLRrSort();
	}
	
	/**中序递归遍历
	 * Inorder Recursion Traversal (LDR)
	 */
	public void LDRrSort(){
		
		if(leftNode!=null) leftNode.LDRrSort();
		System.out.print(data+" ");
		if(rightNode!=null) rightNode.LDRrSort();
	}
	
	/**后序递归遍历
	 * Postorder Recursion Traversal (LRD)
	 */
	public void LRDrSort(){
		
		if(leftNode!=null) leftNode.LRDrSort();
		if(rightNode!=null) rightNode.LRDrSort();
		System.out.print(data+" ");
	}
}
package com.sjh.CustomBinaryTree;

public class MyTree {
	
	private Node rootNode;

	public void add(int x){
		
		Node p = new Node();
		p.data = x;
		if(rootNode == null){
			rootNode = p;
		}else
			rootNode.addNode(p);
	}
	
	public void VLRrSort(){
		if(rootNode==null)
			return ;
		else{
			rootNode.VLRrSort();
			System.out.println();
		}
	}
	
	public void LDRrSort(){
		if(rootNode==null)
			return ;
		else{
			rootNode.LDRrSort();
			System.out.println();
		}
	}
	
	public void LRDrSort(){
		if(rootNode==null)
			return ;
		else{
			rootNode.LRDrSort();
			System.out.println();
		}	
	}
}
package com.sjh.CustomBinaryTree;

public class MyTreeTest {
	
	public static void main(String[] args) {
		MyTree my = new MyTree();
		
		my.add(5);
		my.add(2);
		my.add(4);
		my.add(3);
		my.add(6);
		my.add(1);
		my.add(9);
		my.add(5);

		my.VLRrSort();//前序递归,根左右
		my.LDRrSort();//中序递归,左根右
		my.LRDrSort();//后序递归,左右根
	}
}

输出结果

5 2 1 4 3 6 5 9 
1 2 3 4 5 5 6 9 
1 3 4 2 5 9 6 5 

2.5 HashMap

2.5.1 底层原理

JDK1.7
JDK1.8

2.5.2 基本用法

2.5.3 特点

2.5.4 面试题

三、List--------有序列表

List的特点:可以存在重复的元素,存储顺序有序,可以在任何位置上插入元素,更利于做元素的查找

3.1 Vector--------不建议使用

特点:底层代码结构是动态数组,线程安全,1.2JDK版本,默认容量10
不建议使用的原因:已被淘汰
1.线程安全导致效率低,与StringBuffer类似,有更好的实现线程安全的替代方法
2.只能在尾部进行插入和删除操作,效率低
3.分配内存时需要连续的存储空间,如果数据太多,容易分配内存失败
4.Vector扩容是一倍,ArrayList扩容只需一半
5.JDK向下兼容但不建议使用旧版本的JDK

3.2 ArrayList

3.2.1 基本用法

	al.add(E o);/*添加元素到末尾*/						(boolean)
	al.add(int index, E element);在index处插入element	(void)
	al.clear();/*移除所有元素*/							(void)
	al.clone();/*返回一个副本,复制*/						(object)
	al.contains(Object elem);/*包含elem元素时返回true*/	(boolean)
	al.get(int index);/*返回指定位置index处的元素*/		(E)
	al.isEmpty();/*没有元素时返回true*/					(boolean)
	al.remove(int index);/*移除索引index处的元素*/		(E)
	al.remove(Object o);/*移除o元素的单个实例,只移除一个*/	(boolean)
	//用element替代index处的元素,并返回原来index处的元素
	al.set(int index,E element);						(E)
	al.size();/*返回列表长度*/							(int)
	//如有必要,增加ArrayList实例的容量,指定容量为minCapacity
	//以确保它至少能够容纳最小容量参数(minCapacity)所指定的元素数
	al.ensureCapacity(int minCapacity);					(void)
	//返回elem第一次出现的索引位置,使用equals方法进行相等性测试,未找到返回-1
	al.indexOf(Object elem);							(int)
	//返回elem最后一次出现的索引位置,使用equals方法进行相等性测试,未找到返回-1
	al.lastIndexOf(Object elem);						(int)
	//移除索引在fromIndex(包括)和toIndex(不包括)之间的所有元素
	al.removeRange(int fromIndex, int toIndex);			(protected void)
	//返回一个按照正确的顺序包含此列表中所有元素的数组,对象数组为Object一般不用
	al.toArray();										(Object[])
    //返回一个按照正确的顺序包含此列表中所有元素的数组
    //指定数组是什么类型,返回的就是数组就是什么类型
    al.toArray(T[] a);									(<T> T[])
 	//将此ArrayList实例的容量调整为列表的当前大小,主要用于最小化实例的存储量
 	al.trimToSize();									(void)
	//将指定Collection中的所有元素追加到此向量的末尾,按照指定集合的迭代器所返回的顺序追加这些元素
	al.addAll(Collection<? extends E> c);				(boolean)
	//在index处将指定Collection中的所有元素插入到此向量中
	al.addAll(int index, Collection<? extends E> c);	(boolean)
	//将指定的组件添加到此向量的末尾,将其大小增加1
	al.addElement(E obj);								(void)
package com.sjh.List;

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

public class ArrayListTest1 {

	public static void main(String[] args) {
		
		String[] a1 = new String[8];
		String[] a2 = new String[7];
		String[] a3 = new String[6];
		String[] a4 = new String[5];
		String[] a5 = new String[4];
		
		List<String> list = new ArrayList<String>();
		list.add("3");
		list.add("2");
		list.add("4");
		list.add("6");
		list.add("3");
		list.add("6");
		
		String s = list.set(3,"1");
		
		list.toArray(a1);
		list.toArray(a2);
		list.toArray(a3);
		list.toArray(a4);
		list.toArray(a5);
		
		System.out.println(s);//返回索引3处原来的元素6
		System.out.println(Arrays.toString(a1));//长度超出后面补null
		System.out.println(Arrays.toString(a2));
		System.out.println(Arrays.toString(a3));//尽量保持长度一致
		System.out.println(Arrays.toString(a4));
		System.out.println(Arrays.toString(a5));//长度不足放不进去,全是null
	}
}

输出结果

6
[3, 2, 4, 1, 3, 6, null, null]
[3, 2, 4, 1, 3, 6, null]
[3, 2, 4, 1, 3, 6]
[null, null, null, null, null]
[null, null, null, null]

3.2.2 特点

1.代码底层结构是动态数组
2.线程不同步,线程不安全
3.更擅长做随机访问-遍历
4.添加元素和删除元素的方法,运行速度比LinkedList慢

3.3 LinkedList

3.2.1 基本用法

与ArrayList相同

3.3.2 特点

1.代码底层结构是链表
2.有序—有索引
3.线程不同步,线程不安全
4.实现了队列Queue,说明它是个队列 FIFO(先进先出),LIFO(后进先出)
5.堆栈的实现,队列的实现,以及双端队列的实现
6.LinkedList更擅长做添加和修改以及删除等操作,运行速度要比ArrayList快

Element
Offer
Poll
Peek
Remove
来自于队列的接口

ArrayList和LinkedList各自的使用场合
1.随机访问------遍历------ArrayList
2.插入删除操作较多时------LinkedList
3.线程不安全队列结构------LinkedList
4.线程不安全动态数组------ArrayList

3.3.3 嵌套练习

package com.sjh.List;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

public class TelNote {
	
	private Set<List<Person>> set = null;
	private List<Person> list = null;
	
	public TelNote() {
		set = new HashSet<List<Person>>();
	}
	
	/**
	 *  添加元素
	 * @param p
	 */
	public void add(Person p){
		if(list == null){
			list = new ArrayList<Person>();
		}
		list.add(p);
		set.add(list);
	}
	
	/**
	 * 查找人
	 * @return
	 */
	public Person getPerson(String name){
		
		Iterator<List<Person>> it = set.iterator();
		while(it.hasNext()){
		
			List<Person> persons = it.next();
			for(Person p :persons){
				if(p.getName().equals(name)){
					return p;
				}
			}
		}
		return null;
	}
}
package com.sjh.List;

public class Test1 {
	
	public static void main(String[] args) {
	
		TelNote tel = new TelNote();
		for (int i = 0; i < 5; i++) {
			tel.add(new Person("zhangsanfeng"+i, 99+i));
		}	
		Person p = tel.getPerson("zhangsanfeng1");
		System.out.println(p);
	}
}

3.4 Stack 栈结构

package com.sjh.List;

import java.util.LinkedList;
import java.util.List;
import java.util.Stack;

public class ListTest {
	
	public static void main(String[] args) {
		LinkedList<String> list  = new LinkedList<String>();
		 
		 list.add("123");
		 list.add("345");
		 list.add("1098");
		 list.add("uuu");
		 list.add("ooo");
		 
		 list.addFirst("123");
		 list.addLast("999");
		 
		String key =  list.element();
		 
		 System.out.println(list);
		 System.out.println(key);
		 
		list.getFirst();
		System.out.println(list);
		
		list.offer(null);
		
		String result = list.peek();
		System.out.println(result);
		
		String result1 = list.poll();
		System.out.println(list);
		
		Stack<String> s = new Stack<String>();
		s.push("123");
		s.push("456");
		s.push("90099");
		s.push("163");
		s.push("1200");
		System.out.println(s);
		
		String bRet = s.pop();
		System.out.println(bRet); 
	}
}

未完待续

你可能感兴趣的:(javaSE基础,java,后端,容器,集合)