参考链接:
[https://blog.csdn.net/zhangqunshuai/article/details/80660974]
[(https://blog.csdn.net/zhangqunshuai/article/details/80660974)
https://blog.csdn.net/t_testview/article/details/89014863
参考书籍: Offer来了(Java面试核心知识点)王磊 电子工业出版社

List , Set, Map都是接口,前两个继承至Collection接口,Map为独立接口
Set下有HashSet,LinkedHashSet,TreeSet
List下有ArrayList,Vector,LinkedList
Map下有Hashtable,LinkedHashMap,HashMap,TreeMap
Collection接口下还有个Queue接口,有PriorityQueue类
Java中集合类是放在java.util中,是一个用来存放对象的容器。 1、只能存放对象,不能存放int等类型,存的是对应的是Integer等对象 2、存的是对象的引用,对象本身是放在堆内存中 3、可以存放不同类型的对象(因为实现的时候使用了泛型),不建议使用。
注意:
Queue接口与List、Set同一级别,都是继承了Collection接口。
看图你会发现,LinkedList既可以实现Queue接口,也可以实现List接口.只不过呢, LinkedList实现了Queue接口。Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法 了,而不能直接访问 LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用。
SortedSet是个接口,它里面的(只有TreeSet这一个实现可用)中的元素一定是有序的。

特点: 有序,可重复
特点:不可重复,无序
(1)HashSet
特点:底层数据结构是哈希表。(无序,唯一)
如何来保证元素唯一性?
依赖两个方法:hashCode()和equals()
(2)LinkedHashSet(HashTable实现数据存储,双向链表记录顺序 )
特点:底层数据结构是链表和哈希表。(FIFO插入有序,唯一)
1.由链表保证元素有序
2.由哈希表保证元素唯一
(3)TreeSet
特点:底层数据结构是红黑树。基于二叉树的原理对新添加的对象按照指定的顺序排序(升序或降序),每添加一个对象都会进行排序,并将对象插入二叉树的指定位置。(唯一,有序)
1).如何保证元素唯一性的呢?
根据比较的返回值是否是0来决定
2). 如何保证元素排序的呢?
① 自然排序
代码演示:
把用户类按照名字长度排序,长度相等的按照名字的hash值,如果hash值相等则名字相等,按照年龄排序。
User类:
public class User implements Comparable<User> {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
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
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public int compareTo(User o) {
// return -1; //-1表示放在红黑树的左边,即逆序输出
// return 1; //1表示放在红黑树的右边,即顺序输出
// return 0; //表示元素相同,仅存放第一个元素
// 主要条件 姓名的长度,如果姓名长度小的就放在左子树,否则放在右子树
int num = this.name.length() - o.name.length();
// 姓名的长度相同,不代表内容相同,如果按字典顺序此 String 对象位于参数字符串之前,则比较结果为一个负整数。
// 如果按字典顺序此 String 对象位于参数字符串之后,则比较结果为一个正整数。
// 如果这两个字符串相等,则结果为 0
int num1 = num == 0 ? (this.name.hashCode() - o.name.hashCode()) : num;
// 姓名的长度和内容相同,不代表年龄相同,所以还要判断年龄
int num2 = num1 == 0 ? this.age - o.age : num1;
return num2;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
}
测试类:
import java.util.TreeSet;
public class Demo {
public static void main(String[] args) {
User user1 = new User("zhanggengying", 18);
User user2 = new User("zhoufan", 21);
User user3 = new User("zhoufan", 20);
TreeSet<User> ts = new TreeSet<User>();
ts.add(user1);
ts.add(user2);
ts.add(user3);
for (User user : ts) {
System.out.println(user);
}
}
}
结果:
User [name=zhoufan, age=20]
User [name=zhoufan, age=21]
User [name=zhanggengying, age=18]
② 比较器排序
比较器排序步骤:
代码案例:和上述案例相同,不过是另一种实现方式
//用户类
package com.company.project.test09;
public class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
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
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
User other = (User) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public String toString() {
return "User [name=" + name + ", age=" + age + "]";
}
}
//自己写的比较器
package com.company.project.test09;
import java.util.Comparator;
public class MyComparator implements Comparator<User> {
@Override
public int compare(User s1, User s2) {
// 姓名长度
int num = s1.getName().length() - s2.getName().length();
// 姓名内容
int num2 = num == 0 ? s1.getName().compareTo(s2.getName()) : num;
// 年龄
int num3 = num2 == 0 ? s1.getAge() - s2.getAge() : num2;
return num3;
}
}
//测试类
package com.company.project.test09;
import java.util.TreeSet;
//TreeSet的自然排序
//实现Comparable接口,重写compareTo方法
public class Demo {
public static void main(String[] args) {
User user1 = new User("zhanggengying", 18);
User user2 = new User("zhoufan", 21);
User user3 = new User("zhoufan", 20);
TreeSet<User> ts = new TreeSet<User>(new MyComparator());
ts.add(user1);
ts.add(user2);
ts.add(user3);
for (User user : ts) {
System.out.println(user);
}
}
}
(4)TreeSet, LinkedHashSet and HashSet 的区别
1)介绍:
2)相同点
3)不同点
代码:
package com.company.project.test07;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.TreeSet;
//TreeSet, LinkedHashSet and HashSet的区别
public class Demo {
public static void main(String[] args) {
HashSet<Integer> hashSet = new HashSet<>();
LinkedHashSet<Integer> linkedHashSet = new LinkedHashSet<>();
TreeSet<Integer> treeSet = new TreeSet<>();
for (Integer data : Arrays.asList(5, 4, 3, 6, 8, 9, 10, 50, 30, 90, 111)) {
// hashSet.add(data);
hashSet.add(data);
linkedHashSet.add(data);
treeSet.add(data);
}
// 不保证有序
System.out.println("Ordering in HashSet :" + hashSet);
// FIFO保证安装插入顺序排序
System.out.println("Order of element in LinkedHashSet :" + linkedHashSet);
// 内部实现排序
System.out.println("Order of objects in TreeSet :" + treeSet);
}
}
结果:
Ordering in HashSet :[50, 3, 4, 5, 6, 8, 9, 10, 90, 30, 111]
Order of element in LinkedHashSet :[5, 4, 3, 6, 8, 9, 10, 50, 30, 90, 111]
Order of objects in TreeSet :[3, 4, 5, 6, 8, 9, 10, 30, 50, 90, 111]
针对Collection集合我们到底使用谁呢?(掌握)


特点:
以键值对的形式存放对象。key-value。一般是key为String类型,value为Object的类型。
Map接口有四个比较重要的实现类,分别是HashMap、TreeMap、LinkedHashMap和HashTable。
HashMap的数据结构,内部为数组,数组的每个元素又是一个单向链表,如果单链表的元素超过8个,HashMap又会将链式结构变为红黑树来提高查找效率。
如果想要线程安全,可以用Collections的synchronizedMap方法使HashMap具有线程安全,或者使用ConcurrentHashMap。

HashMap数组+链表结构

HashMap数组+红黑树结构
2.ConcurrentHashMap(分段锁实现,线程安全)
采用分段锁的思想实现并发操作,因此线程安全。
ConcurrentHashMap由多个Segment组成(Segment的数量是锁的并发度),每个Segment都是继承ReentrantLock并单独加锁,所有每次加锁操作是锁住的都是一个Segment,这样只要保证每个Segment都是线程安全的,也就实现了全局的线程安全。

ConcurrentHashMap数组+单向链表结构

ConcurrentHashMap数组+红黑树结构
3.HashTable(线程安全,哈希表)
继承Dictionary类,同一时刻只有一个线程能写HashTable,并发性不如ConcurrentHashMap
4.TreeMap(二叉树数据结构,有序)
实现了SortedMap接口保证元素顺序存储,默认按键值升序存储,也可自定义比较器(实现Comparable接口或者自定义比较器)
5.LinkedHashMap(基于HashTable数据结构,使用链表保存插入顺序)
LinkedHashMap是HashMap的子类,内部使用链表保存元素的插入顺序,通过Iterator遍历LinkedHashMap时,会按照元素的插入顺序访问元素。
(1)HashMap、TreeMap、LinkedHashMap的区别:

(2)Hashtable和HashMap的区别:
(3)如何选择Hashtable和HashMap?
如果对同步性或与遗留代码的兼容性没有任何要求,建议使用HashMap。 查看Hashtable的源代码就可以发现,除构造函数外,Hashtable的所有 public 方法声明中都有 synchronized关键字,而HashMap的源码中则没有。
(4)所有带hash的前缀的Map集合的存储原理:
1、通过内部类Entry进行遍历
2、通过迭代器进行遍历,先获得Entry的Set集合
3、通过keySet方法获得键的Set集合,通过遍历键取值
4、通过map.values()获得所有值,但是不能获得键
代码演示:
package com.company.project.test1001;
import java.util.HashMap;
import java.util.Map;
//Map集合的遍历
public class Demo {
public static void main(String[] args) {
Map<String, String> map = new HashMap<String, String>();
map.put("A", "北京");
map.put("D", "上海");
map.put("C", "广东");
for (Map.Entry<String, String> entry : map.entrySet()) {
System.out.println(entry);
}
}
}
结果:
A=北京
C=广东
D=上海
//1.验证返回状态码是否是200pm.test("Statuscodeis200",function(){pm.response.to.have.status(200);});//2.验证返回body内是否含有某个值pm.test("Bodymatchesstring",function(){pm.expect(pm.response.text()).to.include("string_you_want_to_search");});//3.验证某个返回值是否是100pm.test("Yourtestname",function(){varjsonData=pm.response.json
我正在构建一个小部件来显示奥运会的奖牌数。我有一个“国家”对象的集合,其中每个对象都有一个“名称”属性,以及奖牌计数的“金”、“银”、“铜”。列表应该排序:1.首先是奖牌总数2.如果奖牌相同,按类型分割(金>银>铜,即2金>1金+1银)3.如果奖牌和类型相同,则按字母顺序子排序我正在用ruby做这件事,但我想语言并不重要。我确实找到了一个解决方案,但如果感觉必须有更优雅的方法来实现它。这是我做的:使用加权奖牌总数创建一个虚拟属性。因此,如果他们有2个金牌和1个银牌,加权总数将为“3.020100”。1金1银1铜为“3.010101”由于我们希望将奖牌数排序为最高的,因此列表按降序排
原始问题Letd(n)bedefinedasthesumofproperdivisorsofn(numberslessthannwhichdivideevenlyinton).Ifd(a)=bandd(b)=a,whereab,thenaandbareanamicablepairandeachofaandbarecalledamicablenumbers.Forexample,theproperdivisorsof220are1,2,4,5,10,11,20,22,44,55and110;therefored(220)=284.Theproperdivisorsof284are1,2,
我有以下python函数来递归查找集合的所有分区:defpartitions(set_):ifnotset_:yield[]returnforiinxrange(2**len(set_)/2):parts=[set(),set()]foriteminset_:parts[i&1].add(item)i>>=1forbinpartitions(parts[1]):yield[parts[0]]+bforpinpartitions(["a","b","c","d"]):print(p)有人可以帮我把它翻译成ruby吗?这是我目前所拥有的:defpartitions(set)ifnots
我是ruby开发的新手,我目前正在使用rails2.3.11在ruby1.8.7中开发一个项目,我想知道这种语言是否有与C#的linq等效的集合操作,例如where子句。谢谢。 最佳答案 Ruby中Linq的where等价于find_all检查documentationfortheEnumerableModule用于其他功能。 关于C#的LINQ用于在ruby中等效的集合操作,我们在StackOverflow上找到一个类似的问题: https://
我正在使用reform-railsgem为了在我的Rails项目中使用表单对象。我意识到表单对象对于我在下面使用的示例代码来说可能有点矫枉过正,但它仅用于演示目的。在我创建一个用户的表单中,与该用户记录关联的是两个user_emails。#models/user.rbclassUser请注意,我没有在User模型中使用accepts_nested_attributes_for:user_emails。在我看来,表单对象的要点之一是它可以帮助您摆脱使用accepts_nested_attributes_for,所以这就是为什么我试图在没有它的情况下这样做。我从thisvideo得到了这个
2022年10月21日星期五【数据指标】加密货币总市值:$0.95万亿BTC市值占比:38.51%恐慌贪婪指数:23极度恐慌 【今日快讯】1、【政讯】1.1.1、美联储布拉德:市场预期美联储11月会加息75个基点1.1.2、美联储哈克:将维持加息一段时间1.2、美国10年期国债收益率触及4.197%,为2008年6月以来最高1.3、法国数字转型部长:政府将专注于DeFi和Web31.4、巴西ATM机将于11月3日起支持USDT1.5、美众议院副议长将于11月初加入a16zCrypto担任政府事务主管1.6、香港数字资产托管机构FirstDigitalTrust首席执行官:香港仍是安全
问题localhost:3000/users/不会显示我谦虚地进入,因为我是第一次尝试通过Rails教程。我在第10章,我已经花了5个小时解决这个问题。当我尝试访问localhost:3000/users/时出现错误(我相信这与factory_girl有关)解释了@users变量为空并且我忘记了为will_paginate传递一个集合对象。我目前在第10章第10.23节,每次运行时:$bundleexecrakedb:reset$bundleexecrakedb:populate$bundleexecrakedb:test:prepare我在解释时遇到错误rakeaborted!Fac
我正在为Mechanize而苦苦挣扎。我希望“单击”一组只能通过其位置(div#content中的所有链接)或其href来识别的链接。以上两种识别方法我都试过了,都没有成功。从文档中,我无法弄清楚如何根据链接在DOM中的位置而不是直接通过链接上的属性返回一组链接(用于单击)。其次,documentation建议你可以使用:href来匹配部分href,page=agent.get('http://foo.com/').links_with(:href=>"/something")但我让它返回链接的唯一方法是传递一个完全限定的URL,例如page=agent.get('http://foo
我有两个表与一个连接表连接-这只是伪代码:LibraryBookLibraryBooks我需要做的是,如果我有一个图书馆的id,我想获取该图书馆拥有的所有书籍所在的所有图书馆。因此,如果我有图书馆1,而图书馆1中有书A和B,而书A和B在图书馆1、2和3中,是否有优雅的(单行)方式在rails中执行此操作?我在想:l=Library.find(1)allLibraries=l.books.libraries但这似乎行不通。有什么建议吗? 最佳答案 l=Library.find(:all,:include=>:books)l.books