java 集合总结

集合

一、线性表

在这里十大插入图片描述
1、定义:线性表是一种数据结构。一个线性表是多个元素的有限序列。
2、分类:对于数据不同的逻辑结构,计算机在物理磁盘上通常有两种物理存储结构:
- (1)顺序表、顺序存储结构(线性表):
基本思想:元素的存储空间是连续的。在内存中是以顺序存储,内存划分的区域是连续的。存储结构如下图:
在这里插入图片描述
-(2)链表、链序存储结构(链性表):
基本思想:元素的存储空间是离散的,单独的(物理),它们可以通过在逻辑上指针的联系使得它成为了整体的链表。存储结构如下图:
在这里插入图片描述

1.单链表

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

2.循环链表

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

3.双链表(双向循环表)

在这里插入图片描述
(图有点小问题 :最后一个节点的 指针域 也指向头结点)
在这里插入图片描述

三者的区别(从上面三个图我们可以总结出来):

  • 它们都有数据域(data§)和指针域(next§),但是从图中可以看出双链表有两个指针域,一个指向它的前节点,一个指向它的后节点。
  • 单链表最后一个节点的指针域为空,没有后继节点;循环链表和双链表最后一个节点的指针域指向头节点,下一个结点为头节点,构成循环;
  • 单链表和循环链表只可向一个方向遍历;双链表和循环链表,首节点和尾节点被连接在一起,可视为“无头无尾”;双链表可以向两个方向移动,灵活度更大。
底层实现源码:
class MyLinklist {
	private static class Node {
 //数据域
		private Object data;
//指针域
		private Node next;
		public Node(Object data, Node next) {
			this.data = data;
			this.next = next;
		}
	}
//头结点
	private Node head;
	private int size;
}

*顺序表和链表的对比:

1. 顺序表优点: 可以根据下标计算元素的地址,查找和修改速度快
2. 顺序表缺点: 增加和删除时需要移动大量元素,增删效率低
3. 链式存储的优点: 插入和删除元素时不需要移动元素的位置,效率高
4. 链式存储的缺点:查找和修改元素时必须从头查找,速度慢

二、栈和队列

1、栈
1、 基本思想:

后进先出(先进后出)即栈中元素被处理时,按后进先出的顺序进行,栈又叫后进先出表(LIFO)。
在这里插入图片描述

2.栈的操作:

入栈(push( )),从栈顶增加一个元素
出栈(pop( )),从栈顶删除一个元素
获得栈顶元素,但是不出栈(get( ))
不允许在栈的其它位置插入或删除元素

3、代码实现:
class Stack extends ArrayList {
	public void push( Object obj ) {
		super.add( super.size( ), obj );
	}
	public Object pop( ) {
		return super.remove( super.size( ) - 1 );
	}
	public Object get( ) {
		return super.get( super.size( ) - 1 );
	}
}

很明显Stack继承了ArrayList,代码耦合性高,并不符合java封装的特性 综上所述,引出了聚合:使用聚合关系代替继承关系后,线性表的所有方法被封装起来了,只能通过公开的方法间接地操作线性表,保证了栈中元素的正确性。
具体代码实现:

class Stack {
	private List list = new ArrayList( );
	public void push( Object obj ) {
		this.list.add( this.list.size( ), obj );
	}
	public Object pop( ) {
		return this.list.remove( this.list.size( ) - 1 );
	}
	public Object get( ) {
		return this.list.get( this.list.size( ) - 1 );
	}
}

很明显 Stack类被封装了起来 这样减低了代码的耦合性

2、队列:

基本思想:先进先出即先被接收的元素将先被处理,又叫先进先出表(FIFO)。如下图所示:
在这里插入图片描述

三、Collection集合

1、定义:一个集合是一个对象,也叫容器,用来保存多个其它对象,保存的对象也叫元素。
2.框架结构:

在这里插入图片描述

3、常用方法

方法作用
add( )往集合里添加一个元素添加一个元素
addAll( )往集合里添加另外一个集合
clear()删除这个集合
contains( )是否包含某一个元素(括号里填get(元素下角标))
containsAll()如果此 collection 包含指定 collection 中的所有元素,则返回 true。
isEmpty( )判断集合里是否有元素
remove( )删除集合中的元素
removeAll( )删除集合中包含另一个集合里的元素
retainAll( )移除此 集合中未包含在指定 集合 中的所有元素。
size( )获取集合的长度
toArray( )将当前集合返回为数组(得以Object类型数组接收)

四、list集合

1、list集合特点:

1、List中包含的元素有顺序,通过下标体现
2、List接口除了继承Collection接口中的方法,还增加了一些和下标有关的方法。

方法作用
set()替换集合中元素的值 set(元素位置,替换的值)
indexOf()返回此集合中第一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。
lastIndexOf返回此集合中最后一次出现的指定元素的索引;如果此列表不包含该元素,则返回 -1。
get()返回集合中指定位置的元素。
2、List接口的实现类:

1.Vector:使用数组实现的顺序表,效率低
2.ArrayList:使用数组实现的顺序表,为Vector的替代品,比Vector效率高
3.LinkedList:使用节点组成的双链表
在这里插入图片描述
在这里插入图片描述

3、list集合遍历方法:

1.下标遍历:根据下标访问List集合中的每一个元素的遍历方式,叫做下标遍历。

	List list = new ArrayList();
		list.add("张三");
		list.add("李四");
		list.add("王五");
		for (int i = 0; i < list.size(); i++) {
			System.out.println(list.get(i));
		}

2.for-each遍历:

	List list = new ArrayList();
		list.add("张三");
		list.add("李四");
		list.add("王五"); 
		for ( Object o : list ) {
			System.out.println( o );
		}

3、用迭代器遍历:

	Iterator it = list.iterator( );
		while ( it.hasNext( ) ) {
			System.out.println( it.next( ) );
		}

五、set集合

1、set集合特点:
  1. Set接口中的所有方法都是Collection接口中声明的方法,没有自己增加的方法。
  2. Set集合中没有下标的概念。
2、set集合特点:

1.HashSet:使用数组实现,元素的顺序和放入的顺序无关,底层是由哈希表实现的,哈希表是通过使用称 为散列法的机制来存储信息的,元素并没有以某种特定顺序来存放
2.LinkedHashSet:以元素插入的顺序来维护集合的链接表,元素的顺序和放入的顺序一致
3.TreeSet:可以对元素进行排序的Set集合
在这里插入图片描述
在这里插入图片描述

实例:

HashSet:

	Set set = new HashSet( );
		set.add( "张三" );
		set.add( "李四" );
		set.add( "王五" );
		set.add( "张三" );
		set.add( "王二" );
		set.add( "郭帅哥" );
		System.out.println( set );
;

运行结果:
在这里插入图片描述
出来的顺序和添加顺序不一致 但是相同元素张三不见了。

LinkedHashset:

	Set set = new LinkedHashSet( );
		set.add( "张三" );
		set.add( "李四" );
		set.add( "王五" );
		set.add( "张三" );
		set.add( "王二" );
		set.add( "郭帅哥" );
		System.out.println( set )

运行结果:

出来的顺序和添加顺序一致 而相同元素张三不见了。

treeHashset:

	Set set = new TreeSet( );
		set.add( "张三" );
		set.add( "李四" );
		set.add( "王五" );
		set.add( "张三" );
		set.add( "王二" );
		set.add( "郭帅哥" );
		System.out.println( set );

运行结果:
在这里插入图片描述

出来的顺序和添加顺序并一致(默认按字符排序) 而相同元素张三不见了。

2、 HashSet或LinkedHashSet放入自定义类型的对象:

1、举例:

Set set = new HashSet( );
set.add( new Student(1,"张三" ) );
set.add( new Student(2,"张三" ) );
System.out.println( set );

运行结果:
在这里插入图片描述
很明显 并没有去重

这时我们需要 让Student类重写hashCode( )方法和equals( )方法,让HashSet能够判断两个对象是否重复。

2、解决方案
在这里插入图片描述
所以我们只需要让hashCode( )方法返回值相同这样就可以提高一部分效率

public int hashCode( ) {
	return 0;
}

重写equals( )方法:

 public boolean equals(Object obj) {
        // 如果为同一对象的不同引用,则相同
        if (this == obj) {
            return true;
        }
        // 如果传入的对象为空,则返回false
        if (obj == null) {
            return false;
        }

        // 如果两者属于不同的类型,不能相等
        if (getClass() != obj.getClass()) {
            return false;
        }

        // 将object向下强制转型
        Employee other = (Employee) obj;
      
        //判断两个类体内部内容是否一致
        return Objects.equals(name, other.name) && salary == other.salary && Objects.equals(hireDay, other.hireDay);
    }

3、总结:

  1. 把自定义的对象放入HashSet或LinkedHashSet,为保证元素内容不重复,
  2. 需要: 覆盖hashCode( )方法,保证相同对象返回相同的值,提供调用equals( )方法的机会。
  3. 覆盖equals( )方法,相同对象返回true。
3、 TreeSet排序方式:

TreeSet是能够给元素排序的Set集合,要给元素排序,必须提供排序规则。
有以下两种方法:
1、元素所属的类实现Comparable接口

class Student implements Comparable {
	……
	public int compareTo( Object obj ) {
		return ……//所提供排序规则
		
	}
}

如果一个对象所属的类实现了Comparable接口,则可以直接把这些对象放入TreeSet集合中,TreeSet集合会自动调用对象的compareTo( )方法,根据返回的结果进行排序:

  • 负数:this对象排在obj对象之前
  • 正数:this对象排在obj对象之后
  • 0:视为重复对象

terrset添加对象实例:
创建学生类代码:

 /**
 *创建学生类对象 并实现Comparable接口 
 *
 */
public class WStudent implements Comparable<WStudent>{
/**
 * 创建学生类属性	
 */
	private int id;
	private String name;
	private String  address;
/**
 * 
 * 添加有参构造器 便于创建对象时传值
 * 
 */
	public WStudent(int id,String name,String address){
		this.id = id;
		this.name = name;
		this.address = address;
	}
	/**
	 *实现 Comparable接口 提供排序方法
	 */
	@Override
	public int compareTo(WStudent Stu) {
		//接收id比较的值
		int a = this.id-Stu.id;
		//接收name比较的值,由于object类提供compareTo方法 所以可以直接拿来用
		int b = this.name.compareTo(Stu.name);
		//接收name比较的值,由于object类提供compareTo方法 所以可以直接拿来用
		int c = this.address.compareTo(Stu.address);
		//提供值相等排序方法
		if(a==0){
			if(b==0){
				return c;//如果id相等,姓名相等,按地址排序
			}else{
				return b;//如果id相等,按姓名排序
			}
		}else{
				return a;//按id排序
		}
	}
	//重写学生类toString方法
	@Override
	public String toString() {
		return "WStudent [id=" + id + ", name=" + name + ", address=" + address
				+ "]";
	}
	
	 
}

测试treeset排序方法

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

public class TreeSetCalss {
	public static void main(String[] args) {
		Set<WStudent> set = new TreeSet<WStudent>();
		set.add(new WStudent(1,"郭","北京"));
		set.add(new WStudent(2,"郭","天津"));
		set.add(new WStudent(3,"啊","天津"));
		set.add(new WStudent(2,"啊","天津"));
		set.add(new WStudent(1,"郭","天津"));
		System.out.println(set);
	}
}

运行结果如下:

2、使用实现了Comparator接口的对象创建TreeSet对象
如果希望可以对某一类对象按照多个规则进行不同的排序,可以使用Comparator实现类的对象创建TreeSet集合:

Set set = new TreeSet ( new Comparator( ) {
	public int compare( Object o1, Object o2 ) {
		return ( ( Student ) o1 ).getAge( ) 
			- ( ( Student ) o2 ).getAge( );
	}
} );

terrset添加对象实例:
创建学生类:

 public class WStudent  
{
	/**
	 * 创建学生类属性
	 */
	private int id;
	private String name;
	private String address;

	/**
	 * 
	 * 添加有参构造器 便于创建对象时传值
	 * 
	 */
	public WStudent(int id, String name, String address) {
		this.id = id;
		this.name = name;
		this.address = address;
	}
	public WStudent( ) {
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

 

	//重写学生类toString方法
	@Override
	public String toString() {
		return "WStudent [id=" + id + ", name=" + name + ", address=" + address
				+ "]";
	}
}

创建测试类,并提供排序方法

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class TreeSetCalss{
	public static void main(String[] args) {
		Set<WStudent> set = new TreeSet<WStudent>(new MyTreeSet());//匿名内部类
		set.add(new WStudent(1,"郭","北京"));
		set.add(new WStudent(2,"郭","天津"));
		set.add(new WStudent(3,"啊","天津"));
		set.add(new WStudent(2,"啊","天津"));
		set.add(new WStudent(1,"郭","天津"));
		System.out.println(set);
 
	} 
}
/**
 *提供TreeSet排序方法
 *
 *实现Comparator接口
 *
 */
class MyTreeSet implements Comparator<WStudent> {
    
	@Override
	//重写compare方法
	public int compare(WStudent o1, WStudent o2) {		
		//接收id比较的值
		int a = o1.getId()-o2.getId();
		//接收name比较的值,由于object类提供compareTo方法 所以可以直接拿来用
		int b = o1.getName().compareTo(o2.getName());
		//接收name比较的值,由于object类提供compareTo方法 所以可以直接拿来用
		int c = o1.getAddress().compareTo(o2.getAddress());
		if(a==0){
			if(b==0){
			    return c;//如果id相等,姓名相等,按地址排序
			}else{
				return b;//如果id相等,按姓名排序
			}
		}else{
				return a;//按id排序
		}
	}
	
  
}

使用Comparator实现类的对象创建的TreeSet集合不会使用对象的compareTo( )方法排序,所以不要求对象所属的类必须实现Comparable接口。TreeSet集合根据compare( )方法返回的结果进行排序:

  • 负数:o1对象排在o2对象之前
  • 正数:o1对象排在o2对象之后
  • 0:视为重复对象

两种排序方式比较:

  • 使用Comparable只能对对象按照一个规则排序,使用Comparator可以对对象按照多个规则排序,更加灵活。
  • 可以把多个Comparator实现类的对象作为待排序对象的静态内部类,使用时从对象中获取。
  • 两种排序方法不冲突,可以同时使用。
4、set集合遍历方法:

由于Set集合中没有下标的概念,无法通过下标获得元素,无法使用下标遍历。

所以有以下两种方法:
1、用迭代器遍历

Iterator it = set.iterator( );
while ( it.hasNext( ) ) {
	System.out.println( it.next( ) );
}

2、用for-each遍历:

    Set set = new HashSet();
    …… // 向set中增加元素
    for ( Object o : set ) {
    	System.out.println( o );
    }

六、map集合

1、集合特点:
  1. Map接口是一个独立的接口,和Collection接口没有任何关系。
  2. 每个元素不是一个对象,而是两个对象。
    键对象(key):不能重复
    值对象(value):可以重复
    Map集合中的一个键值对是一个整体,不能分开。
2.map集合常用方法:
方法作用
put( )添加元素
putAll()将另一个集合中的元素全部添加到集合当中
get( )获取元素
remove( )删除元素
clear( )清空集合当中的元素
size( )集合的长度
isEmpty()如果此映射未包含键-值映射关系,则返回 true。
containsValue如果此映射将一个或多个键映射到指定值,则返回 true。
containsKey()如果此映射包含指定键的映射关系,则返回 true。
3.map的实现类:
  • HashMap:无序的键值对的集合,为Hashtable的替代品,比HashTable效率高,线程不安全,可以存空值
  • LinkedHashMap:使用链表实现的键值对的集合,键值对的顺序和放入的顺序一致
  • TreeMap:可以对键值对按照键对象排序的Map集合,键对象需要实现Comparable接口
  • HashTable :线程安全,效率低,不允许存储空值。
  • Properties:键对象和值对象都是String类型的哈希表,常用来读写配置文件

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

4.map的三种遍历

由于map本身是不支持迭代器的,但是map提供了将其元素导入Collection的方法,我们可以将map集合导入Collection的集合当中在进行遍历。
具体操作如下:
1.键遍历

Set<Integer> set = map.keySet();//将map集合中的键值用set集合进行接收
		/**
		* 迭代器遍历
		*
		*/
		Iterator<Integer> it = set.iterator();
		while (it.hasNext()) {
			System.out.println(it.next());
		}

2.值遍历

	Collection<String> coll = map.values();//将map集合转入Collection的视图表中
		/**
		 * 迭代器遍历
		 * 
		 */
		Iterator<String> it = coll.iterator();
		while (it.hasNext()) {
			System.out.println(it.next());
		}

3.键值遍历

 	Set<Entry<Integer, String>> set = map.entrySet();//将map集合中的键值对转入Set集合中
		/**
		 * 迭代器遍历
		 * 
		 */
		Iterator<Entry<Integer, String>> it = set.iterator();
		while (it.hasNext()) {
			System.out.println(it.next());
		}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值