集合(ArrayList,HashMap,HashSet)详解+ entrySet的应用

最近总遇到要用 Map 的题
这里写一下我的学习笔记
主要参考来自github–JavaGuide项目(超超超超超级推荐!!!)
(文章最后会附上链接)

例题引入——直线

在平面直角坐标系中,两点可以确定一条直线。如果有多点在一条直线上,那么这些点中任意两点确定的直线是同一条。

在这里插入图片描述

题意分析

  • 重点:直线—》怎么确定一条直线?—》直线方程 y = kx +b —》k,b确定一条直线
  • 直线不重复–》想到要用Set集合—》用HashSet(重复的元素根本就不会存进去)
  • 求k,b!!!这我竟然忘了咋求了!!
    在这里插入图片描述

根据下面的参考代码,自己模仿的

import java.util.*;
//import java.util.Map.Entry;

//import com.sun.org.apache.bcel.internal.generic.IINC;

public class Main{
	public static void main(String[] args) {
		//创建 HashSet集合,存放 k,b
		HashSet<Map<Double, Double>> sets = new HashSet<>();
		//创建 ArrayList集合 ,存放 点坐标
		ArrayList<Map<Integer, Integer>> list = new ArrayList<>();
		
		for(int i=0;i<20;i++) {
			for(int j=0;j<21;j++) {
				Map<Integer, Integer> map = new HashMap<>();
				map.put(i, j);
				list.add(map);	//点坐标放到ArrayList中
			}
		}
		
		//遍历ArrayList,计算其对应的k和b
		double x1 = 0,y1 = 0,x2 = 0,y2 = 0;	//要定义为double类型--》后面要用点坐标 计算k和b的值
		for(int i=0;i<list.size();i++) {
			//对于list集合中的每一个点,都去与它后面的所有点连线
			for(int j=i+1;j<list.size();j++) {
				//计算两点确定的一条直线的k,b
				//获取两点坐标
				for(Map.Entry<Integer, Integer> entry : list.get(i).entrySet()) {
					x1 = entry.getKey();
					y1 = entry.getValue();
				}
				for(Map.Entry<Integer, Integer> entry : list.get(j).entrySet()) {
					x2 = entry.getKey();
					y2 = entry.getValue();
				}
				//先不计算平行于x轴和y轴的那些直线
				if(x1 == x2 || y1 == y2) {
					continue;
				}
				//根据坐标点 计算k,b
				double k = (y1-y2)/(x1-x2);
				double b = (y1*x2-y2*x1)/(x2-x1);
				//创建一个临时的map--》打包k,b
				HashMap<Double,Double> temp = new HashMap<>();
				temp.put(k, b);
				//把map放到HashSet集合中---》Set集合天然的不添加重复元素---》最后Set集合的长度就是kb对的长度--》也就是确定唯一直线的个数
				sets.add(temp);
			}
		}
		System.out.println(sets.size()+20+21);
	}
}

参考代码(加一点点我的小tips)

代码参考于 蓝桥官网—— “求求你别黑我家哥哥了” 大佬
在这里插入图片描述

import java.util.*;
// 1:无需package
// 2: 类名必须Main, 不可修改

public class Main {
    public static void main(String[] args) {
        HashSet<Map<Double,Double>> lines = new HashSet<>();
        List<Map<Integer,Integer>> list = new ArrayList<>();

        for (int i = 0; i < 20; i++) {
            for (int j = 0; j < 21; j++) {
            	//map中存放的kv对是点坐标
                Map<Integer,Integer> map = new HashMap<>();
                map.put(i,j);
                //再把map放到list中。也就是说,现在list中每一个index 存放的都是一个map集合(就是一个kv对表示的坐标点x,y)
                list.add(map);
            }
        }

        //得到两个直线点
        double x1=0,x2=0,y1=0,y2=0;
        //从list.get(0)开始,遍历每一个 index=0 之后的点 (也就是两点连线)
        for (int i = 0; i < list.size(); i++) {
            for (int j = i+1; j < list.size(); j++) {
            	//得到i中的map的kv对的值(也就是出发点的坐标k=x,v=y)
                for (Map.Entry<Integer, Integer> entry : list.get(i).entrySet()) {
                    x1 = entry.getKey();
                    y1 = entry.getValue();
                }
                //同理,得到j中的map(k,v)
                for (Map.Entry<Integer, Integer> entry : list.get(j).entrySet()) {
                    x2 = entry.getKey();
                    y2 = entry.getValue();
                }
                //先不计算所有平行于x轴,y轴的直线
                if (x1 == x2 || y1 == y2) {
                    continue;
                }
                //计算出 这两点对应的k,b的值
                double k = (y2 - y1) / (x2 - x1);
                double b = (x2 * y1 - x1 * y2) / (x2 - x1);
                //k,b值存放到一个map集合中
                Map<Double, Double> temp = new HashMap<>();
                temp.put(k, b);
                //把这个map集合放到HashSet集合中--》自动的 重复的k,b只会存进去一次
                lines.add(temp);
            }
        }
        //最后,lines中有多少个map集合,那就有多少条不重复的直线---》这里需要加上之前刨除的平行于x轴和y轴的那些直线
        System.out.println(lines.size()+20+21);
    }
}

基于这段代码,开启这篇文章

============================================

1.java集合引入

java集合,也叫做容器,主要是由两大接口派生而来:
Collection接口,用于存放单一元素;
Map集合,主要存放键值对。

对于Collection接口,下面又有三个主要的子接口:List、Set和Queue

  • java集合框架(概览)如下:
    在这里插入图片描述

2.为什么要使用集合?

当我们需要存储一组类型相同的数据时,数组是最常用且最基本的容器之一。但是,使用数组存储对象存在一些不足之处,因为在实际开发中,存储的数据类型多种多样且数量不确定。这时,Java
集合就派上用场了。与数组相比,Java 集合提供了更灵活、更有效的方法来存储多个数据对象。Java
集合框架中的各种集合类和接口可以存储不同类型和数量的对象,同时还具有多样化的操作方式。相较于数组,Java
集合的优势在于它们的大小可变、支持泛型、具有内建算法等。总的来说,Java
集合提高了数据的存储和处理灵活性,可以更好地适应现代软件开发中多样化的数据需求,并支持高质量的代码编写。

3.List、Set、Queue和Map的区别

简单的说:

  • List:有顺序
  • Set:元素不可重复
  • Queue:排队
  • Map:用key来搜索value
  • List:存储的元素都是有序的、可重复的
  • Set:存储的元素不可重复
  • Queue:按特定的排队规则来确定先后顺序,存储的元素是有序的、可重复的
  • Map:使用键值对(key-value)存储,类似于数学上的函数y=f(x),“x”代表key,“y”代表value。key是无序的、不可重复的;value是无序的、可重复的,每个键最多映射到一个值。

4.List

  • ArrayList
  • Vector
  • LinkedList

List——ArrayList

- ArrayList的底层是数组队列,相当于动态数组。
- 与java中的数组相比,它的容量能动态增长。
- 在添加大量元素前,应用程序可以使用ensureCapacity操作来添加ArrayList实例的容量
  • ArrayList 继承于AbstractList,实现了List,RandomAccess,Cloneable,java.io.Serializable这些接口。

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable{

  }

  • ArrayList实现的功能也和这些接口有关
    • List:表明它是一个列表,支持添加、删除、查找等操作,并且可以通过下标进行访问
    • RandomAccess:这是一个标志接口,表明实现这个接口的List集合是支持快速随机访问的。在ArrayList中,我们既可以通过元素的序号快速获取元素对象,这就是快速随机访问。
    • Cloneable:表明它具有拷贝能力,可以进行深拷贝或浅拷贝操作。
    • Serializable:表明它可以进行序列化操作,也就是可以将对象转换为字节流进行持久化存储或网络传输。

(!!实用!!)ArrayList常用方法

  • add(E element):将指定元素添加到列表的末尾
	ArrayList<Integer> list = new ArrayList<Integer>();
	list.add(123);
	list.add(45);
	list.add(666);
	System.out.println(list);	//output:[123, 45, 666]

	ArrayList<String> s = new ArrayList<String>();
	s.add("hfies");
	s.add("jeif");
	s.add("fose");
	System.out.println(s);	//output:[hfies, jeif, fose]
  • add(int index,E element):在指定位置插入指定元素
	list.add(2, 9999);
	System.out.println(list);	//output:[123, 45, 9999, 666]
  • get(int index):返回指定位置的元素
	System.out.println(list.get(2));	//output:9999
	//也可用于循环输出
	for(int i=0;i<list.size();i++) {
		System.out.print(list.get(i)+" ");	//output:123 45 9999 666
	}
  • set(int index,R element):替换指定位置的元素
	list.set(2, 8888);
	System.out.println(list);//output:[123, 45, 8888, 666]
  • remove(int index):移除指定位置的元素
	list.remove(2);
	System.out.println(list);//output:[123, 45, 666]
  • size():返回列表中的元素数目
	System.out.println(list.size());//output:3
  • clear():清空列表中的所有元素
	list.clear();
	System.out.println(list);//output:[]
  • contains(Object o):判断列表是否包含指定元素
	System.out.println(list.contains(666));//output:true
  • indexOf(Object o):返回指定元素在列表中第一次出现的位置
	System.out.println(list.indexOf(45));//output:1
  • isEmpty():判断列表是否为空
	System.out.println(list.isEmpty());//output:false
  • clone():复制数组
	Object o = list.clone();
	System.out.println(o);//output:[123, 45, 666]
  • 全部代码:
import java.util.*;;

public class Main{
	public static void main(String[] args) {
		ArrayList<Integer> list = new ArrayList<Integer>();
		list.add(123);
		list.add(45);
		list.add(666);
		System.out.println(list);	//output:[123, 45, 666]
		
		ArrayList<String> s = new ArrayList<String>();
		s.add("hfies");
		s.add("jeif");
		s.add("fose");
		System.out.println(s);	//output:[hfies, jeif, fose]
		
		list.add(2, 9999);
		System.out.println(list);	//output:[123, 45, 9999, 666]
		
		System.out.println(list.get(2));	//output:9999
		for(int i=0;i<list.size();i++) {
			System.out.print(list.get(i)+" ");	//output:123 45 9999 666
		}
		System.out.println();
		
		list.set(2, 8888);
		System.out.println(list);//output:[123, 45, 8888, 666]
		
		list.remove(2);
		System.out.println(list);//output:[123, 45, 666]

		System.out.println(list.size());//output:3
		
		System.out.println(list.contains(666));//output:true
		
		System.out.println(list.indexOf(45));//output:1
		
		System.out.println(list.isEmpty());//output:false
		
		Object o = list.clone();
		System.out.println(o);//output:[123, 45, 666]
		
		list.clear();
		System.out.println(list);//output:[]
	}
}

//output:
在这里插入图片描述

List——Vector

List——LinkedList

这两个我还没用到过,用到会来补充

5.Set

HashSet:无序,唯一
TreeSet:有序,唯一
LinkedHashSet

  • HashSet:基于HashMap实现的,底层采用HashMap来保存元素。
  • LinkedHashSetLinkedHashSetHashSet的子类,并且其内部是通过LinkedHashMap来实现的。
  • TreeSet:红黑树(自平衡的排序二叉树)

6.Map

HashMap

  • map.put()
	Map<Integer,String> map = new HashMap<>();
	map.put(1, "1a");
	map.put(2, "2a");
	map.put(3, "3a");
	System.out.println(map);	//output:{1=1a, 2=2a, 3=3a}


	//当给map中添加元素,会返回key对应的原来的value值;若key没有对应的值,返回null
	System.out.println(map.put(1, "5"));	//output:1a
	System.out.println(map);	//output:{1=5, 2=2a, 3=3a}
  • map.get()
	//根据指定的key获取对应的value
	String s = map.get(2);
	System.out.println(s);	//output:2a
  • map.remove()
	//根据key删除元素,会返回key对应的value值
	String value = map.remove(2);
	System.out.println(value);	//output:2a
	System.out.println(map);	//output:{1=5, 3=3a}

HashSet

HashSet是基于HashMap来实现的,实现了Set接口,同时还实现了序列化和可克隆化。
而集合Set是不允许有重复值的。
所以HashSet是一个没有重复元素的集合但不保证集合的迭代顺序(所以,随着时间改变,元素的顺序可能会改变)
由于HashSet是基于HashMap来实现的,所以允许空值不是线程安全

  • HashSet是基于HashMap实现的,区别就在于HashMap中输入一个键值对,而在HashSet中只输入一个值。

  • 构建HashSet

HashSet<E> hs = new HashSet<E>();
//也可以写成
Set<E> hs = new HashSet<E>();
  • add():因为HashSet不会存在重复元素,所以相同的元素不会存进去
  • 常用方法:
    在这里插入图片描述

entrySet

entrySet就是用来遍历map的一种方法

entrySet是java中键值对的集合,Set里面的类型是Map.Entry,一般可以通过map.entrySet()得到。

  • entrySet实现了Set接口,里面存放的是键值对
Set<Map.Entry<String,String>> entryseSet = map.entrySet();

for(Map.Entry<String,String> entry:entryseSet){
	System.out.println("key= ” + entry.getKey + "," + "value= " + entry.getValue()):
}

参考文档

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值