java基础-容器
已经写了一段时间JAVA代码了,但仔细想来,却发现对JAVA的很多方面还是一片迷茫。
利用周末补一下基础知识吧。
大致列一下这个周末需要学习的内容
1 容器 (本节内容)
2 线程
3 流
目录
1 接口List Set Collection Comparable
2 工具类 Collections
3 Set 的去重原理
4 hashcode equals 的重写
5 Iterator接口实现的的遍历(List Set Map)
一、容器
接口:Collection 接口定义了容器的基本操作,List,Set接口都是Collection的子接口
List接口
List接口的主要实现类有我们常用的ArrayList,LinkList,允许重复且是有序的。
ArrayList与LinkList区别
ArrayList的get,set会比较快,因为LinkList需要移动指针。
LinkList的add,remove会比较快,因为ArrayList需要移动数据。
Collections类提供对List对象进行排序的静态方法,但List里面的对象必须实现comparable接口
例1 Collections打乱顺序的方法shuffle
package test; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; public class test {
String name;
String id;
test(String id,String name){
this.id=id;
this.name=name;
} public static void main(String[] args) {
List list = new ArrayList();
test t1 = new test("","a");
test t2 = new test("","C");
test t3 = new test("","b");
list.add(t1);list.add(t2);list.add(t3); Collections.shuffle(list); //打乱顺序
// Collections.sort(list); for(Object obj: list){
test res =(test)obj;
System.out.println(res.getId()+" "+res.getName()+" / hashCode : "+res.hashCode());
}
}
public String getName() {
return name;
}
public String getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public void setId(String id) {
this.id = id;
}
}
结果
b / hashCode :
C / hashCode :
a / hashCode :
顺序已经打乱
例2 Collections排序方法sort
Collections.sort(list);
结果
Exception in thread "main" java.lang.ClassCastException: test.test cannot be cast to java.lang.Comparable
at java.util.Arrays.mergeSort(Arrays.java:)
at java.util.Arrays.sort(Arrays.java:)
at java.util.Collections.sort(Collections.java:)
at test.test.main(test.java:)
如果List里面的对象没有实现Comparable接口的话,是不能进行排序的,
所以需要改一下代码实现Comparable接口,代码如下。
package test; import java.util.ArrayList;
import java.util.Collections;
import java.util.List; public class test implements Comparable{//实现Comparable接口
String name;
String id;
test(String id,String name){
this.id=id;
this.name=name;
} @Override
public int compareTo(Object obj) {//把compareTo写完整,按ID排序 --->用对象(obj)的id与自己的id比较大小
test t = (test)obj;
return this.id.compareTo(t.getId());
} public static void main(String[] args) {
List list = new ArrayList();
test t1 = new test("","a");
test t2 = new test("","C");
test t3 = new test("","b");
list.add(t1);list.add(t2);list.add(t3); Collections.shuffle(list); //打乱顺序
Collections.sort(list); for(Object obj: list){
test res =(test)obj;
System.out.println(res.getId()+" "+res.getName()+" / hashCode : "+res.hashCode());
}
}
public String getName() {
return name;
}
public String getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public void setId(String id) {
this.id = id;
}
}
结果
a / hashCode :
b / hashCode :
C / hashCode :
排序成功
Set接口
Set接口的主要实现类有我们常用的HashSet 是不允许重复且无序的。
Set是如何去重的
1 每当Set需要Add一个对象的时候,会先去找对象的HashCode并检查这个HashCode位置上有没有已经存在的对象
2 如果没有存在对象,就正面不重复可以添加至容器
3 如果存在对象,则通过equal方法进行比较如果不相同则可以添加,如果相同则不添加到容器中
这算法的好处是减少每次添加数据时候的比较次数,比如容器里面已经有N个对象,那么一个个去equal就得比较N次,而这样最多比较1-2次
4 如果每次都是New一个对象放入的时候,如果要需要去重,那么必须重写 int hashCode和equals方法
注意:HashCode通常情况下表示地址,但并不是地址,因为hashCode可以背重写。
getClass().getName() + "@" + Integer.toHexString(hashCode()),jdk对toString方法的实现。
例1 new三个一样内容的对象添加入set容器(不重写hashcode)
package test; import java.util.HashSet;
import java.util.Set; public class test {
String name;
String id;
test(String id,String name){
this.id=id;
this.name=name;
} public static void main(String[] args) {
Set set = new HashSet();
test t1 = new test("","a");
test t2 = new test("","a");
test t3 = new test("","a");
set.add(t1);set.add(t2);set.add(t3);
for(Object obj: set){
test res =(test)obj;
System.out.println(res.getId()+" "+res.getName()+" / hashCode : "+res.hashCode());
} }
public String getName() {
return name;
}
public String getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public void setId(String id) {
this.id = id;
}
}
结果
a / hashCode :
a / hashCode :
a / hashCode :
因为每个对象被NEW出来的时候都被新分配了一个内存地址,所以hashcode是不一样的
所以通过了Set的hashcode校验。
例2 new三个一样内容的对象添加入set容器,重写hashcode(不重写equals方法)
package test; import java.util.HashSet;
import java.util.Set; public class test {
String name;
String id;
test(String id,String name){
this.id=id;
this.name=name;
}
@Override //重写了hashCode方法,hashCode都为0
public int hashCode(){
return ;
} public static void main(String[] args) {
Set set = new HashSet();
test t1 = new test("","a");
test t2 = new test("","a");
test t3 = new test("","a");
set.add(t1);set.add(t2);set.add(t3);
System.out.println("T1与T2用equals方法进行比较 "+t1.equals(t2));//这里只比较T1和T2
for(Object obj: set){
test res =(test)obj;
System.out.println(res.getId()+" "+res.getName()+" / hashCode : "+res.hashCode());
} }
public String getName() {
return name;
}
public String getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public void setId(String id) {
this.id = id;
}
}
结果
T1与T2用equals方法进行比较 false
a / hashCode :
a / hashCode :
a / hashCode :
虽然hashCode已经相同,但通过使用equals方法进行下一步比较的结果是false,所以Set容器判断为并不重复,所以仍然通过了校验
例2 new三个name一样,id不一样的对象添加入set容器,重写hashcode、重写equals方法(针对name重复)
package test; import java.util.HashSet;
import java.util.Set; public class test {
String name;
String id;
test(String id,String name){
this.id=id;
this.name=name;
}
@Override //重写了hashCode方法,hashCode都为0
public int hashCode(){
return ;
}
@Override
public boolean equals(Object obj){
test t = (test)obj;
return this.name.equals(t.getName());//这里重写如果名字相同就返回true,否则返回false
} public static void main(String[] args) {
Set set = new HashSet();
test t1 = new test("","a");
test t2 = new test("","a");
test t3 = new test("","a");
set.add(t1);set.add(t2);set.add(t3);
System.out.println("T1与T2用equals方法进行比较 "+t1.equals(t2));//这里只比较T1和T2
for(Object obj: set){
test res =(test)obj;
System.out.println(res.getId()+" "+res.getName()+" / hashCode : "+res.hashCode());
} }
public String getName() {
return name;
}
public String getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public void setId(String id) {
this.id = id;
}
}
结果
T1与T2用equals方法进行比较 true
a / hashCode :
重写hashcode和equals的方法使得对象在添加进入Set容器时可以有效的去重。
Iterator 接口的遍历
Iterator接口可以对List和Set容器进行遍历
package test; import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set; public class test {//实现Comparable接口
String name;
String id;
test(String id,String name){
this.id=id;
this.name=name;
} public static void iterator(Iterator it){ //iterator 遍历
while(it.hasNext()){
test t =(test) it.next();
System.out.print(t.getName()+"\r\n");
}
} public static void main(String[] args) {
test t1 = new test("","BB");
test t2 = new test("","AA");
Set set = new HashSet(); //SET
set.add(t1);set.add(t2); List list = new ArrayList(); //LIST
list.add(t1);list.add(t2); Iterator it = set.iterator();
test.iterator(it);
Iterator it1 = list.iterator();
test.iterator(it1);
}
public String getName() {
return name;
}
public String getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public void setId(String id) {
this.id = id;
}
}
结果
AA//SET
BB
BB//LIST
AA
List和Set都有iterator()方法,可以转换为iterator对象进行遍历
MAP对象也可以通过自带的keySet()方法转化成Set后进行Iterator进行遍历
package test; import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set; public class test {//实现Comparable接口
String name;
String id;
test(String id,String name){
this.id=id;
this.name=name;
} public static void iterator(Iterator it,Map map){ //iterator 遍历
while(it.hasNext()){
String key =it.next().toString();
test res = (test)map.get(key);
System.out.println(res.getName());
}
} public static void main(String[] args) {
test t1 = new test("","BB");
test t2 = new test("","AA"); Map map = new HashMap();
map.put("", t1);map.put("", t2); Set mapset =map.keySet();
Iterator it = mapset.iterator();
test.iterator(it,map);
}
public String getName() {
return name;
}
public String getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public void setId(String id) {
this.id = id;
}
}
1 使用map.keySet转换成set对象
2 转换后调用iterator()转成Iterator对象后进行遍历
3 遍历出的结果为key,调用map.getKey方法获得值
java基础-容器的更多相关文章
- JAVA基础--容器 Set, List, Map
Colections接口, Iterator接口, Set接口, List接口, Comparable接口, Map接口 Collections类 容器:装各种对象. 所有容器都在java.util里 ...
- 【转】Java基础——容器分类
Java容器可以说是增强程序员编程能力的基本工具,本系列将带您深入理解容器类. 容器的用途 如果对象的数量与生命周期都是固定的,自然我们也就不需要很复杂的数据结构. 我们可以通过创建引用来持有对象,如 ...
- java基础-容器-Set
Set:set不存重复元素,如果是使用set存储java预定义的Integer,String等类型会很简单,如果是存储自定义类型的数据类型,就必须要重新定义equals()方法以确保set中保存的对象 ...
- java基础 容器 API
- JAVA基础(9)——容器(3)——并发容器
转载:http://blog.csdn.net/weitry/article/details/52964509 JAVA基础系列规划: JAVA基础(1)——基本概念 JAVA基础(2)——数据类型 ...
- java面试:java基础、Io、容器
1.java基础 1.JDK 和JRE有什么区别 JDK:java开发工具包,java开发运行环境.包含了JRE. JRE:java运行环境,包含java虚拟机,java基础类库. 2.jav ...
- [Java面经]干货整理, Java面试题(覆盖Java基础,Java高级,JavaEE,数据库,设计模式等)
如若转载请注明出处: http://www.cnblogs.com/wang-meng/p/5898837.html 谢谢.上一篇发了一个找工作的面经, 找工作不宜, 希望这一篇的内容能够帮助到大 ...
- Java基础知识【上】(转载)
http://blog.csdn.net/silentbalanceyh/article/details/4608272 (最终还是决定重新写一份Java基础相关的内容,原来因为在写这一个章节的时候没 ...
- Java基础应用
Java集合类解析 List.Map.Set三个接口,存取元素时,各有什么特点? List 以特定次序来持有元素,可有重复元素.Set 无法拥有重复元素,内部排序.Map 保存key-value值,v ...
随机推荐
- Redis多机数据库
复制 PSYNC命令具有完整重同步(full resynchronization)和部分重同步(partial resynchronization)两种模式: ·其中完整重同步用于处理初次复制情况:完 ...
- System.FormatException: GUID 应包含带 4 个短划线的 32 位数(xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)。解决办法
查一下数据库的UID数据是否格式正确,如: 错误格式1: {E056BB36-D824-4106-A9C3-D8D8B9ADC1C 错误格式2: E056BB36-D824-4106-A9C3-D8D ...
- 123apps-免费网络应用
前言 在Jianrry`s博客看见推荐这个网址,试用了一下感觉还不错.主要是完全免费!!就当备用吧 网站介绍 123apps 网站地址:https://123apps.com/cn/ 旗下网站: PD ...
- 五、react中父子组件间如何传值
1.父组件向子组件传递数据:父组件绑定属性值传给子组件,子组件通过this.props()接受. 2.子组件向父组件传递数据:子组件绑定一个方法,方法中通过this.props.父组件方法名(参数)传 ...
- C# 目录下的文件操作
运用DirectoryInfo类的对象我们可以轻松的实现对目录以及和目录中的文件相关的操作,假如你要获得某个目录F:\Pictures下的所有BMP文件,那么通过下面的代码就可以实现该功能. 上面的代 ...
- 【SAM manacher 倍增】bzoj3676: [Apio2014]回文串
做法一:PAM:做法二:SAM+manacher.前缀树上倍增 Description 考虑一个只包含小写拉丁字母的字符串s.我们定义s的一个子串t的“出 现值”为t在s中的出现次数乘以t的长度.请你 ...
- 二十、Mysql 连接的使用
Mysql 连接的使用 在前几章节中,我们已经学会了如何在一张表中读取数据,这是相对简单的,但是在真正的应用中经常需要从多个数据表中读取数据. 本章节我们将向大家介绍如何使用 MySQL 的 JOIN ...
- Linux-WebServer安装和配置
Apache 基本操作 解释 命令 安装 yum install httpd 启动 service httpd start 停止 service httpd stop 启动完成后 查看进程是否存在:p ...
- 分享自己写的基于Dapper的轻量级ORM框架~
1.说明 本项目是一个使用.NET Standard 2.0开发的,基于 Dapper 的轻量级 ORM 框架,包含基本的CRUD以及根据表达式进行一些操作的方法,目前只针对单表,不包含多表连接操作. ...
- vue.js 服务端渲染nuxt.js反向代理nginx部署
vue.js的官方介绍里可能提到过nuxt.js,我也不太清楚我怎么找到这个的 最近项目vue.js是主流了,当有些优化需求过来后,vue还是有点力不从心, 比如SEO的优化,由于vue在初始化完成之 ...