【Java】Java学习笔记10-集合Collection

集合

数据结构基本知识

基本数据结构

数据结构:

数据:计算机中存储元素

结构:数据与数据之间的关系

常用的数据和数据之间的关系:

数据结构包括两个层次(角度)

(1)逻辑结构:数据与数据之间的逻辑结构

​ 包含四种结构:线性结构,树形结构,图状结构,集合结构

(2)物理结构:数据在计算机中真实的存储结构

​ 包含两种:顺序存储和链式存储(在内存片上,一个是连续存储,一个是不连续存储)

常用的几种结构:

(1)数组(一位线性存储)物理角度 一维顺序线性表

(2)链表

(3)堆栈

(4)队列

(5)树

(6)哈希表

其中数组、链表、堆栈、队列-------逻辑上是线性存储

堆栈、队列:受限的线性存储

特殊说明:

会把常用的数据结构:分为线性表(顺序线性表、线性链表)。。。数组概念升级成特殊的

角度不同:

数组:(从物理结构角度)

线性表:(从逻辑结构角度)

顺序线性表:数组(一维数组)+线性表

1.数组

从物理结构上划分的数组,不是java中的数组

【定义】使用一组地址连续的存储单元,依次存储线性表的数组元素

【数组中元素的访问】

每个元素所占用的空间是一样的size大小

首地址+偏移量(n*size)

对于每个元素访问时候的效率都是一样的,O(1)常数时间复杂度

【使用场景】

(1)java中的数组使用数据结构中结构中的静态数组,一组地址连续的存储单元

思考 为什么java中的数组但初始化了,就不能修改长度

先申请一片内存,要存储十个,最后一个元素length属性

原因:如果扩充了java中的数组大小,无法断定连续地址的后面有没有内存空间,如果没有空间,接着其他的

​ java的数变成非连续的存储,无法访问

(2)数据结构中“动态数组”

动态数组:可以进行库容,也是在原来的静态数组的基础上形成,代价:效率慢

List list=new ArrayList(); 就是使用动态数组 来存储

2.链表

一个元素“挨着”另一个元素,不是非要连续存储

【定义】是线性(数据和数据之间的关系),但是不是连续存储

链表中的节点可以分成两个部分:

主句与:存储数据

指针域:下一个元素的地址

随机访问性:没有数组好,访问每个元素的效率不同 时间复杂度O(0)

对于元素进行插入和删除效率比数组高:只需要修改指针域即可

大多数的存储都是优先选择数据结构

【了解】链表:单项链表和双向链表

双向链表:一定程度上优化了单项链表的访问性,但是增加了添加元素,删除元素的复杂度

3.堆栈

栈:线性存储(元素和元素之间有关系)受限制的线性表

栈顶:口()出入口

栈底:第一个进入的元素所放的位置

规则:先进后出LIFO

【使用场合】

方法的调用

A–B--C–D--E目的是为了接住返回值

异常的向上传播,异常抛出给调用者

4.队列

队列:线性存储(为了表达元素和元素之间的关系),受限的线性表

队头:第一个进入的元素:(出)

队尾:最后一个进入的元素:(入)

规则:先进先出FIFO

【场合】处理多线程

【了解】也可以有双端队列,可以进行队头和队尾的添加和删除元素,可以实现栈的存储

缺点:添加和删除元素

5.树

节点集合连接每对节点的有向边集组成

二叉树:特征每个节点(除叶子节点以外)都只有不超过两个节点(0个,1个,2个)

满二叉树:除叶子节点以外,每个节点都有两个子节点。

​ 对满二叉树进行编号:从上到下,从左到右

完全二叉树:当一个二叉树的所有节点编号,都跟满二叉树保持一致,称为完全二叉树

遍历树:对树中所有的节点进行访问

广度遍历:按照层次遍历,先爷爷,找父辈或者父辈兄弟

深度遍历:爷爷–父亲–儿子

掌握的内容:对于二叉树的遍历:

针对于“根节点”

先序遍历:中左右

中序遍历:左中右

后序遍历:左右中

6.哈希表

希望将一组数据存储到内存中一组有序的存储单元中(不是按照一对一的存储)

存储规则:按照哈希规则进行存储

数学中的规则y=f(x)哈希函数的规则

假如:y=x%7 一定会将众多的x存储到7个存储单元中

【好处】当我们访问元素的时候。都可以是常数时间复杂度

【问题】都会采用hashcode中扩展,两种方法,重新计算hashcode,存入下一个地址

也可以对单一地址进行扩展,扩展成新的数组

将一组关键字(数据)根据哈希函数(规则),映射到一个有限的地址集上,这种结构的表称为hash表

【场合】

java中的map key value

查找和排序

查找:准确的说查找的方法有三种:顺序查找;二分查找;分块查找

排序:冒泡、选择、插入、希尔排序、快速、归并

插入排序
【规则】:从第二个元素开始,插入到现有的已排好序的数组中,保证前小后大的排序
希尔排序
【规则】:改进版的插入排序(最小增量排序)分组
增量:inc 将i个元素和i+inc、i+2inc 、i+3inc…
每次进行分组,对每一组的元素进行(插入)排序,注意的是,每个元素的原来位置保持不变
增量设置的规则:没有 原则:从大到小 每次取一半 6 3 1
假设增量为3 2 1

public class Day13_1_con {
//	希尔排序
	public  static void shell(int[] t,int []increment){
		//int[] t={3,-2,5,10,-9,11,7,-1};
		for (int inc : increment) {
//			每一个增量下的每一组
			for(int k=0;k<inc;k++){
				for(int i=k+inc;i<t.length;i+=inc){
					int temp=t[i];
					int j= i-inc;  
					while(j>=0&&temp<t[j]){
						t[j+inc]=t[j];
						j-=inc;
					}
					t[j+inc]=temp;
					System.out.println(Arrays.toString(t));
				}
			}
		}

}
//	插入排序
 	public static void insert(int []t){
		//int[] t={3,-2,5,10,-9,11,7,-1};
		//int[] t={-2,3,5,10,-9,11,7,-1};
		//int[] t={-9,-2,3,5,10,11,7,-1};
		//int[] t={-9,-2,3,5,j+1,10,11,-1};  temp=7
		for(int i=1;i<t.length;i++){
//			int i=1;   //没有排好对的第一个元素(正在排序的元素)
			int temp=t[i];//正在排序的元素值
			int j= i-1;  //排好队的最后一个元素
			while(j>=0&&temp<t[j]){
				t[j+1]=t[j];
				j--;
			}
			t[j+1]=temp;
		}

}

//	每次都找到最小的元素,放在前面(注意:每次找到最小值的索引,再跟当前元素交换位置)
	public static void choose(int []t){
		for(int i=0;i<t.length-1;i++){
			int min_index=i;
			for(int j=i+1;j<t.length;j++){
				if (t[min_index]>t[j]){
					min_index=j;
				}
			}
			int temp=t[i];
			t[i]=t[min_index];
			t[min_index]=temp;
		}
	}
	
//	相邻的两个元素之间进行比较,如果不符合前小后大的的原则,交换
	public static void bubble(int []t){
		boolean tag=true;
		for (int j=0;j<t.length-1;j++){
			for(int i=0;i<t.length-1-j;i++){
				if(t[i]>t[i+1]){
					int temp=t[i];
					t[i]=t[i+1];
					t[i+1]=temp;
					tag=false;
				}
			}
	        if(tag){
	        	break;
	        }
		}
	}

public static void binarySearch(int[] t,int key){
	Arrays.sort(t);
	int start=0;
	int end=t.length-1;
	boolean tag=true;
	while(start<=end){
		int mid=(start+end)/2;
		if(key==t[mid]){
			System.out.println("找到了");
			tag=false;
			break;
		}else if(key<t[mid]){
			end=mid-1;
		}else{
			start=mid+1;
		}
	}
	if(tag){
		System.out.println("不存在");
	}
}
public static void main(String[] args) {
	int[] t={3,-2,5,10,-9,11,7,-1};
//		binarySearch(t,30);
//		bubble(t);
//		insert(t);
//		choose(t);
		shell(t,new int[]{3,2,1});
		System.out.println(Arrays.toString(t));
}
}

集合

【集合】容器类,集合也可以看成一个容器,能够容纳多个元素的容器

数组的最大缺点:声明之后,长度不能再更改,同时,对于数组操作也很麻烦

Collection接口

所有集合类的根接口,最直接的子接口Set List

Map是独立出来的接口:键值对的形式存储数据

(一)collection接口

不能实例化对象。选择ArrayList作为实现类,来创建对象

接口引用 c=new ArrayList();

c.add(); AarryList下实现的方法

1.集合下的相关方法

public class Day13_2_Collection {
public static void main(String[] args) {
  Collection<Integer> c=new ArrayList<Integer>();
  Collection<Integer> c2=new ArrayList<Integer>();

添加相关
(1)add 向集合中添加元素,如果添加成功会返回true,否则返回false
当实现类是Set的实现类的时候,如果有重复元素,则不能添加成功

  System.out.println(c.add(11));

​ (2)addAll(集合类型的对象) 将参数指定的所有元素都加入到当前集合
返回值:当前集合发生变化的时候,就会返回true,否则则返回false(如果一个都加不进去才会false)

c2.add(22);
c.addAll(c2);
for (Integer integer : c) {
	System.out.println(integer);
}

跟集合大小
(3)size 返回集合中元素的个数
判断一个集合类型是不是空(没有元素)的,尽量不要用对象!=null

public List a(){ return list.getSize()>0?list:null;}
其他调用a的人  List b=a();  if(b=null)
System.out.println(c==null);

​ (4)isEmpty判断集合是否为空

System.out.println(c.isEmpty());

​ (5)判断集合是否包含某一个对象

c.add(10);
System.out.println(c.contains(10));

​ (6)c.containsAll(另外一个集合) 判断c中是否包含另外一个集合中的所有元素

c2.add(10);
c.add(10);
c.add(11);
System.out.println(c.containsAll(c2));

跟删除相关
(7)remove(Object o)删除集合中的某个元素
当删除不成功(没有这个元素),会返回false,成功则返回true

c.add(10);
c.add(11);
System.out.println(c.remove(12));
for (Integer integer : c) {
		System.out.println(integer);
}

​ (8)removeAll(另外一个集合) 删除集合中,另外一个集合的所有元素(删除交集)
​ 如果当前集合发生变化,返回true,如果一个元素都没删除,则返回false

c2.add(10);
c.add(11);
c.addAll(c2);
c.removeAll(c2);
for (Integer integer : c) {
		System.out.println(integer);
}

​ (9)c.removeIf(filter) Predicate中test方法:按照实现类的规则进行筛选数据。

for (int i = 0; i < 10; i++) {
	c.add(i);
}
c.removeIf((Integer t)->t>5);
for (Integer integer : c) {
	System.out.println(integer);
}

​ (10)retainall(集合类型):将参数集合中存在于当前集合的元素保留下来(保留下交集)

for (int i = 0; i < 10; i++) {
	c.add(i);
}
for (int i = 0; i < 9; i++) {
	c2.add(i);
}
c.retainAll(c2);
for (Integer integer : c) {
	System.out.println(integer);
}
c.forEach(System.out::println);

​ (11)clear清空给所有元素

c.add(11);
c.clear();
System.out.println(c.isEmpty());

​ (12)toArray 能将集合对象转换成数组

for (int i = 0; i < 10; i++) {
	c.add(i);
}
Object[] i= c.toArray();
System.out.println(Arrays.toString(i));

​ (13) c.toArray(数组) 将c的集合中的元素,装入到参数的数组中。

Integer[] array=new Integer[c.size()];
c.toArray(array);
System.out.println(Arrays.toString(array));
}
}

2.集合的遍历

(1)使用iterator接口。(原始方法)
(2)使用iterator接口。(1.8之后新增的方法)
(3)增强for循环
(4)forEach方法
(5)使用聚合操作

(1)使用iterator接口。(原始方法)
next获得下一个元素
hasnext 用来 判断是否还有下一个元素
remove 删除最后一个next元素:

public class Day13_2_Collection {
	public static void main(String[] args) {
	    Collection<Integer> c=new ArrayList<Integer>();
	    c.add(10);
	    c.add(11);
	    c.add(12);
	    Iterator<Integer> it=c.iterator();//获得集合下的迭代器(迭代器是集合根本)

​ 迭代器中 会存储集合中的元素 ,如果迭代器中的元素全部被访问完毕,再继续调用next会报错
​ 可以看成迭代器是一次性。

		System.out.println(it.next());
	    System.out.println(it.next());
	    System.out.println(it.next());

每次在for循环的开头位置当便利完毕元素之后,重新创建一个迭代对象。

	 c.iterator()
	    for (Integer i : c) {
			System.out.println(i);
		}
	    for (Integer i : c) {
			System.out.println(i);
		}
    while(it.hasNext()){
    	Integer ite=it.next();
    	System.out.println(ite);
    }

​ remove:删除刚刚访问过 next()的元素 ,如果没有访问过,直接运行remove会报错

    System.out.println(it.next());//10
    it.remove();
    System.out.println(c.contains(10));

编程的时候,需要注意的地方:
对于集合元素中进行迭代器的遍历时,不要同时对集合帝乡进行添加、删除元素(不要边遍历边删除、添加)会发生并行修改的异常。

	    while (it.hasNext()){
	    	System.out.println(it.next());
	    	c.remove(11);

(2)Iterator接口 1.8之后新增接口

public class Day13_2_Collection {
	public static void main(String[] args) {
		Collection<Integer> c=new ArrayList<Integer>();
	    c.add(10);
	    c.add(11);
	    c.add(12);
	    Iterator<Integer> it=c.iterator();
//	    it.forEachRemaining((Integer i)->System.out.println(i));
//	    it.forEachRemaining(i->System.out.println(i));
//	    it.forEachRemaining(System.out::println);
	}
}

(3)增强for循环
(4)foreach方法

public class Day13_2_Collection {
	public static void main(String[] args) {
		Collection<Integer> c=new ArrayList<Integer>();
	    c.add(10);
	    c.add(11);
	    c.add(12);
	    c.forEach(System.out::println);
	}
}

(5) 使用聚合操作

public class Day13_2_Collection {
	public static void main(String[] args) {
		Collection<Integer> c=new ArrayList<Integer>();
	    c.add(10);
	    c.add(11);
	    c.add(12);
	    c.stream().forEach(System.out::println);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值