java学习_5_23
Collection接口中定义的方法如下,所有继承自Collection接口的接口(List,Set)的实现类均实现了这些方法。

List容器是有序、可重复的,常用的实现类:ArrayList,LinkedList,Vector(线程安全的)

带索引的add,remove操作。
自己实现的MyArrayList:
package test.stringTest;
public class MyArrayList<E> {
private Object[] elementData;
// 元素个数
private int size;
// 数组默认长度
private final static int DEFAULT_CAPACITY = 10;
public MyArrayList() {
elementData = new Object[DEFAULT_CAPACITY];
}
public MyArrayList(int length) {
if (length <= 0)
throw new RuntimeException("容器容量值需为正整数:" + length);
elementData = new Object[length];
}
public void add(E element) {
if (size == elementData.length)
grow();
elementData[size++] = element;
}
@SuppressWarnings("unchecked")
public E get(int index) {
if (indexInRange(index))
return (E) elementData[index];
else
throw new RuntimeException("索引越界:" + index);
}
public void remove(E element) {
int index = -1;
for (int i = 0; i < size; i++) {
if (element.equals(elementData[i])) {
index = i;
break;
}
}
if (index != -1) {
remove(index);
}
}
public void remove(int index) {
if (!indexInRange(index)) {
throw new RuntimeException("索引越界:" + index);
}
int numMoved = elementData.length - index - 1;
if (numMoved > 0) {
System.arraycopy(elementData, index + 1, elementData, index, numMoved);
} else {
elementData[index] = null;
}
size--;
}
private boolean indexInRange(int index) {
return index < size && index >= 0 ? true : false;
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0 ? true : false;
}
// 数组扩容
private void grow() {
Object[] newArray = new Object[elementData.length + (elementData.length >> 1)];
System.arraycopy(elementData, 0, newArray, 0, elementData.length);
elementData = newArray;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[");
for (int i = 0; i < size; i++) {
sb.append(elementData[i].toString() + ",");
}
sb.setCharAt(sb.length() - 1, ']');
return sb.toString();
}
public static void main(String[] args) {
MyArrayList<String> list = new MyArrayList<>(20);
int i = 0;
while (i <= 50) {
list.add("aaa" + i);
i++;
}
System.out.println(list);
System.out.println(list.get(31));
System.out.println(list.size());
list.remove(21);
list.remove("aaa4");
System.out.println(list);
System.out.println(list.size);
System.out.println(list.isEmpty());
}
}
HashMap底层实现:数组加链表(JDK8以后当元素个数超过8时,会转变为红黑树结构)。首先根据Key计算出hashcode,然后根据hashcode,利用hash算法计算出数组的下标,然后将值放入该下标数组存储的链表中(有重复(equals比较)的key值则覆盖) 两个相同的对象必须具有相同的hashcode。
/**
* The table, initialized on first use, and resized as
* necessary. When allocated, length is always a power of two.
* (We also tolerate length zero in some operations to allow
* bootstrapping mechanics that are currently not needed.)
*/
transient Node<K,V>[] table;
/**
* Basic hash bin node, used for most entries. (See below for
* TreeNode subclass, and in LinkedHashMap for its Entry subclass.)
*/
static class Node<K,V> implements Map.Entry<K,V> {
final int hash;
final K key;
V value;
Node<K,V> next; Node(int hash, K key, V value, Node<K,V> next) {
this.hash = hash;
this.key = key;
this.value = value;
this.next = next;
}
..........
自己实现的HashMap:
package test.stringTest;
public class MyHashMap<K,V> {
Node<K,V>[] table; // 位桶数组
int size;
public MyHashMap() {
table = new Node[16];
}
public void put(K key, V value) {
Node<K,V> node = new Node<>();
node.key = key;
node.value = value;
node.next = null;
node.hash = myHash(key, table.length);
Node<K,V> temp = table[node.hash];
Node<K,V> lastNode = temp;
boolean isOverride = false; // 有没被覆盖
if (temp == null) {
table[node.hash] = node;
size++;
} else {
while (temp != null) {
// key相同 则覆盖
if (temp.key.equals(key)) {
temp.value = value;
isOverride = true;
break;
} else {
// 不同 则继续向下遍历
lastNode = temp;
temp = temp.next;
}
}
// 没有覆盖发生 则将Node添加到后面
if (!isOverride) {
lastNode.next = node;
size++;
}
}
}
public Object get(Object key) {
int hash = myHash(key, table.length);
Node<K,V> temp = table[hash];
if (temp != null) {
while (temp != null) {
if (temp.key.equals(key))
return temp.value;
else
temp = temp.next;
}
}
return null;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder("{");
for (int i = 0; i < table.length; i++) {
Node<K,V> temp = table[i];
while (temp != null) {
sb.append(temp.key + ":" + temp.value + ",");
temp = temp.next;
}
}
sb.setCharAt(sb.length() - 1, '}');
return sb.toString();
}
private int myHash(Object key, int length) {
return key.hashCode() % length;
}
public static void main(String[] args) {
MyHashMap<String,Integer> map = new MyHashMap<>();
map.put("aaa", 111);
map.put("bbb", 222);
map.put("ccc", 333);
map.put("ddd", 444);
map.put("aae", 555);
map.put("ccc", 666);
map.put("rre", 777);
map.put("aaa", 321);
System.out.println(map.size);
System.out.println(map.get("ccc"));
}
}
class Node<K,V> {
int hash;
K key;
V value;
Node<K,V> next;
}
java学习_5_23的更多相关文章
- 0037 Java学习笔记-多线程-同步代码块、同步方法、同步锁
什么是同步 在上一篇0036 Java学习笔记-多线程-创建线程的三种方式示例代码中,实现Runnable创建多条线程,输出中的结果中会有错误,比如一张票卖了两次,有的票没卖的情况,因为线程对象被多条 ...
- 0035 Java学习笔记-注解
什么是注解 注解可以看作类的第6大要素(成员变量.构造器.方法.代码块.内部类) 注解有点像修饰符,可以修饰一些程序要素:类.接口.变量.方法.局部变量等等 注解要和对应的配套工具(APT:Annot ...
- 分享篇——我的Java学习路线
虽然之前我是开发出身,但是我学习的语言是Objective-c,这个语言使用起来范围比较窄,对于自动化学习来说也是无用武之地,所以我自己学习了Java,对于一个有开发经验的人来说学习一门新语言相对来说 ...
- Java学习笔记(04)
Java学习笔记(04) 如有不对或不足的地方,请给出建议,谢谢! 一.对象 面向对象的核心:找合适的对象做合适的事情 面向对象的编程思想:尽可能的用计算机语言来描述现实生活中的事物 面向对象:侧重于 ...
- Java学习心得之 HttpClient的GET和POST请求
作者:枫雪庭 出处:http://www.cnblogs.com/FengXueTing-px/ 欢迎转载 Java学习心得之 HttpClient的GET和POST请求 1. 前言2. GET请求3 ...
- 0032 Java学习笔记-类加载机制-初步
JVM虚拟机 Java虚拟机有自己完善的硬件架构(处理器.堆栈.寄存器等)和指令系统 Java虚拟机是一种能运行Java bytecode的虚拟机 JVM并非专属于Java语言,只要生成的编译文件能匹 ...
- 0030 Java学习笔记-面向对象-垃圾回收、(强、软、弱、虚)引用
垃圾回收特点 垃圾:程序运行过程中,会为对象.数组等分配内存,运行过程中或结束后,这些对象可能就没用了,没有变量再指向它们,这时候,它们就成了垃圾,等着垃圾回收程序的回收再利用 Java的垃圾回收机制 ...
- 0028 Java学习笔记-面向对象-Lambda表达式
匿名内部类与Lambda表达式示例 下面代码来源于:0027 Java学习笔记-面向对象-(非静态.静态.局部.匿名)内部类 package testpack; public class Test1{ ...
- 0025 Java学习笔记-面向对象-final修饰符、不可变类
final关键字可以用于何处 修饰类:该类不可被继承 修饰变量:该变量一经初始化就不能被重新赋值,即使该值跟初始化的值相同或者指向同一个对象,也不可以 类变量: 实例变量: 形参: 注意可以修饰形参 ...
随机推荐
- C# 插件热插拔 .NET:何时应该 “包装异常”? log4.net 自定义日志文件名称
C# 插件热插拔 所谓热插拔就是插件可以 在主程序不重新启动的情况直接更新插件, 网上有很多方案: https://www.cnblogs.com/happyframework/p/3405811 ...
- 【Android基础】App签名与打包
签名的意义 1. 为了保证程序开发人员的合法 2. 防止部分人通过使用同样的Package Name(包名)来混淆替换已安装的程序 3. 保证我们每次公布的版本号的一致性(保证签名一致才干升级) 签名 ...
- UM九图
UML有9种图: 用例图类图对象图状态图序列图协作图活动图组件图部署图 9,在中国是个阳数,通常代表很多的意思.比如说,九九艳阳天,九死而不悔,成吉思汗对功臣的九罪而不罚,天上九头鸟地上湖北佬,等等. ...
- 通过shell脚本批处理es数据
#!/bin/sh [按照指定的域名-website集合,遍历各个域名,处理url] #指定待删除的变量集合 arr=(6.0) cur="`date +%Y%m%d%H%M%S`" ...
- ASP.NET调用存储过程并接收存储过程返回值
ASP.NET调用存储过程并接收存储过程返回值 2010-08-02 11:26:17| 分类: C#|字号 订阅 2010年02月27日 星期六 23:52 假设表结构Create T ...
- Tarjan求桥
传送门(poj3177) 这道题是Tarjan求桥的模板题.大意是要求在原图上加上数量最少的边,使得整张图成为一个边双联通分量. 具体的做法是,先在图中求出所有的桥,之后把边双联通分量缩成点,这样的话 ...
- matlab绘制曲线对比图
>> clear;>> x1=[0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8];>> y1=[0,0.55,0.69,0.86,0.93,0. ...
- LVS的持久连接、会话保持和高可用介绍
持续连接 1)持久连接(lvs persistence)模板: 实现无论使用任何调度算法,在一段时间内(默认360s),能够实现将来自同一个地址的请求始终发往同一个RS ipvsadm -A|E -t ...
- Google C++编程规范 – 第十九条 -《前置声明》
转自:http://roclinux.cn/?p=3285 本原创文章属于<Linux大棚>博客. 博客地址为http://roclinux.cn. 文章作者为roc wu == [规范] ...
- 【js】再谈移动端的模态框实现
移动端模态框的机制因为与PC的模态框机制一直有所区别,一直是许多新人很容易踩坑的地方,最近笔者作为一条老咸鱼也踩进了一个新坑中,真是平日里代码读得太粗略,故而写上几笔,以儆效尤. 故事的起因是这样的, ...