知识点:Java 集合框架图

总结:Java 集合进阶精讲1

总结:Java 集合进阶精讲2-ArrayList

集合进阶1---为集合指定初始容量

集合在Java编程中使用非常广泛,当容器的量变得非常大的时候,它的初始容量就会显得很重要了.

因为扩容是需要消耗大量的人力物力财力的。

同样的道理,Collection的初始容量也显得异常重要。所以:对于已知的情景,请为集合指定初始容量。

import java.util.ArrayList;
import java.util.List; public class ColTest { public static void main(String[] args) {
Base_User baseUser = null;
long begin1 = System.currentTimeMillis();
List<Base_User> list1 = new ArrayList<Base_User>();
for(int i = 0 ; i < 1000000; i++){
baseUser = new Base_User(i,"chenssy_"+i,i);
list1.add(baseUser);
}
long end1 = System.currentTimeMillis();
System.out.println("list1 time:" + (end1 - begin1)); long begin2 = System.currentTimeMillis();
List<Base_User> list2 = new ArrayList<>(1000000);
for(int i = 0 ; i < 1000000; i++){
baseUser = new Base_User(i,"chenssy_"+i,i);
list2.add(baseUser);
}
long end2 = System.currentTimeMillis();
System.out.println("list2 time:" + (end2 - begin2));
} }

分析:

插入1000000条数据,list1没有没有申请初始化容量,而list2初始化容量1000000。运行结果我们可以看出list2的速度是list1的两倍左右。

ArrayList的扩容机制是比较消耗资源的。我们先看ArrayList的add方法:

public boolean add(E e) {
ensureCapacity(size + 1);
elementData[size++] = e;
return true;
} public void ensureCapacity(int minCapacity) {
modCount++; //修改计数器
int oldCapacity = elementData.length;
//当前需要的长度超过了数组长度,进行扩容处理
if (minCapacity > oldCapacity) {
Object oldData[] = elementData;
//新的容量 = 旧容量 * 1.5 + 1
int newCapacity = (oldCapacity * 3)/2 + 1;
if (newCapacity < minCapacity)
newCapacity = minCapacity;
//数组拷贝,生成新的数组
elementData = Arrays.copyOf(elementData, newCapacity);
}
}

ArrayList每次新增一个元素,就会检测ArrayList的当前容量是否已经到达临界点,如果到达临界点则会扩容1.5倍。

然而ArrayList的扩容以及数组的拷贝生成新的数组是相当耗资源的。

大数据量的前提下,指定初始化容量,效率的提升和资源的利用会显得更加具有优势。

集合进阶2---使用entrySet遍历Map集合KV

HashMap的遍历有两种常用的方法,那就是使用keyset及entryset来进行遍历

但两者的遍历速度是有差别的。

第一种: entryset 效率高

Map map = new HashMap();
Iterator iter = map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Object key = entry.getKey();
Object val = entry.getValue();
}

第二种: keySet 效率低

Map map = new HashMap();
Iterator iter = map.keySet().iterator();
while (iter.hasNext()) {
Object key = iter.next();
Object val = map.get(key);
}

对于keySet其实是遍历了2次,一次是转为iterator,一次就从hashmap中取出key所对于的value。

而entryset只是遍历了第一次,他把key和value都放到了entry中,所以就快了。

集合进阶3---合理利用集合的稳定性和有序性

合理利用集合的稳定性(order)和有序性(sort),避免集合的无序性和不稳定性带来的负面影响。

  • 稳定性指集合每次遍历的元素次序是一定的。
  • 有序性是指遍历的结果按某种比较规则依次排序的。

ArrayList是order/unsort,HashMap是unorder/unsort,TreeSet是order/sort,还可以通过TreeSet结合ArrayList对结果进行排序。

Java 常用集合的一些特征:

  • ①、LinkedList 底层是双向链表。ArrayList:底层采用数组结构,里面添加的元素有序可以重复。

  • ②、HashSet:底层采用哈希表算法,里面添加的元素无序不可重复。

  • ③、HashMap:底层也是采用哈希表算法,但是里面添加的元素是 key-value 的形式。key 不允许重复,value 可以。

如何好好利用这些集合的原理,简化我们的编程呢。

1、统计一字符串中每个字符出现的次数?

解析:给定一串字符串,统计每个字符出现的次数。统计的字符是不能重复的,而出现的个数我们可以不用管。那么很容易联想到 Map 的集合原理,key-value。我们将统计的字符放在 Map<Character,Integer>中是一种很好的实现方式。

HashMap

import java.util.HashMap;
import java.util.Map; public class CnTest { public static Map<Character, Integer> countChar(Map<Character, Integer> map,String str){
//将所给的字符串解析为一个字符构造的数组
char[] chars = str.toCharArray(); for(char c : chars){
if(map.containsKey(c)){
int oldCount = map.get(c);
map.put(c, oldCount+1);
}else{
map.put(c, 1);
}
} return map;
} public static void main(String[] args) {
String str = "hello world";
//定义一个 Map 集合,用来存放统计的 字符--个数
Map<Character, Integer> hashMap = new HashMap<Character, Integer>();
System.out.println(countChar(hashMap,str));
//{w=1, d=1, =1, e=1, r=1, o=2, l=3, h=1}
}
}

补充:这里我们用来保存统计字符的是 HashMap 的实现类,这里打印出来的字符统计是无序的。

LinkedHashMap

根据字符串给定的顺序有序的统计出

         public static void main(String[] args) {
String str = "hello world";
//定义一个 Map 集合,用来存放统计的 字符--个数
Map<Character, Integer> linkedHashMap = new LinkedHashMap<Character, Integer>();
System.out.println(countChar(linkedHashMap,str));
//{h=1, e=1, l=3, o=2, =1, w=1, r=1, d=1}
}

TreeMap

用 uicode 的编码顺序打印给定的字符串

     public static void main(String[] args) {
String str = "hello world";
//定义一个 Map 集合,用来存放统计的 字符--个数
Map<Character, Integer> treeMap = new TreeMap<Character, Integer>();
System.out.println(countChar(treeMap,str));
//{ =1, d=1, e=1, h=1, l=3, o=2, r=1, w=1}
}

二、去掉给定数组重复的数据?

解析:将数组中的元素都放到Set,然后将 Set 集合转变为数组就可以了。

import java.util.HashSet;
import java.util.Set; public class CrTest { public static Integer[] clearRepeat(int [] array){
Set<Integer> set = new HashSet<Integer>();
for(int i : array){
set.add(i);
}
Integer[] newArray = set.toArray(new Integer[set.size()]);
return newArray;
} public static void main(String[] args) {
//创建一个数组,可以看出 2和4 是重复的
int [] array = {1,2,3,4,2,2,3,4};
Integer[] newArray = clearRepeat(array);
for(Integer i : newArray){
System.out.println(i);
}
//1 2 3 4 }
}

同理我们可以改变 Set 集合的实现类,hashSet 是无序的,我们可以会用** LinkedHashSet** 保证既定顺序;TreeSet 保证自然顺序

over

by:一只阿木木

总结:Java 集合进阶精讲1的更多相关文章

  1. 总结:Java 集合进阶精讲2-ArrayList

    知识点:Java 集合框架图 总结:Java 集合进阶精讲1 总结:Java 集合进阶精讲2-ArrayList 初探: ArrayList底层结构是数组,是List接口的 可变数组的实现,所以会占用 ...

  2. Java集合详解8:Java集合类细节精讲,细节决定成败

    <Java集合详解系列>是我在完成夯实Java基础篇的系列博客后准备开始写的新系列. 这些文章将整理到我在GitHub上的<Java面试指南>仓库,更多精彩内容请到我的仓库里查 ...

  3. Java集合详解8:Java集合类细节精讲

    今天我们来探索一下Java集合类中的一些技术细节.主要是对一些比较容易被遗漏和误解的知识点做一些讲解和补充.可能不全面,还请谅解. 本文参考:http://cmsblogs.com/?cat=5 具体 ...

  4. Java代理模式精讲之静态代理,动态代理,CGLib代理

    代理(Proxy)是一种设计模式,通俗的讲就是通过别人达到自己不可告人的目的(玩笑). 如图: 代理模式的关键点是:代理对象与目标对象.代理对象是对目标对象的扩展,并会调用目标对象 这三个代理模式,就 ...

  5. Java内存模型精讲

    1.JAVA 的并发模型 共享内存模型 在共享内存的并发模型里面,线程之间共享程序的公共状态,线程之间通过读写内存中公共状态来进行隐式通信 该内存指的是主内存,实际上是物理内存的一小部分 2.JAVA ...

  6. 【JAVA】笔记(8)--- java.lang.String 精讲

    String 特性: 1.String 表示字符串类型,属于引用数据类型,所以其储存的是地址: 2.java 中规定,双引号括起来的字符串是不可变的,也就说" name "永远也只 ...

  7. 知识点:Java 集合框架图

    知识点:Java 集合框架图 总结:Java 集合进阶精讲1 总结:Java 集合进阶精讲2-ArrayList Java集合框架图 我们经常使用的Arrayist.LinkedList继承的关系挺复 ...

  8. Java集合详解8:Java的集合类细节精讲

    Java集合详解8:Java集合类细节精讲 今天我们来探索一下Java集合类中的一些技术细节.主要是对一些比较容易被遗漏和误解的知识点做一些讲解和补充.可能不全面,还请谅解. 本文参考:http:// ...

  9. 8千字干货教程|java反射精讲

    java反射机制精讲 目录 1. 反射机制的概念 2. 反射的基础Class类 3. 反射的用法 4. 反射的应用示例 作者简介:全栈学习笔记,一个正在努力的人 微信公众号:公众号日更,精彩美文每天推 ...

随机推荐

  1. spring boot多模块项目找不到类

    项目结构 mapper依赖pojo, service依赖mapper和pojo portal依赖pojo和service. 全都是maven模块 <groupId>com.haitian& ...

  2. RabittMQ安装和Erlang安装教程

    安装Erlang 官方安装地址文档: http://www.rabbitmq.com/install-rpm.html 根据官网的推荐 进入到专为RabbitMQ整理的极简版Erlang https: ...

  3. 【转】.Net Core中的Api版本控制

    原文链接:API Versioning in .Net Core 作者:Neel Bhatt 简介 Api的版本控制是Api开发中经常遇到的问题, 在大部分中大型项目都需要使用到Api的版本控制 在本 ...

  4. day32-python阶段性复习六

    面向对象编程的一种方法一些皆对象面向过程和面向对象编程面向过程编程:函数式编程.c等面向对象编程:c++ ,java,python等看具体问题用哪种方法 类和对象:是面向对象中的两个重要的概念类:是对 ...

  5. Django进阶之CSRF

    简介 django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成.而对于django中设置防跨站请求伪造功能有 ...

  6. Ubuntu系统下安装免驱动摄像头

    最近想玩一下视频系列的深度学习模型,便网上淘了一个linux下免驱动的摄像头,直接插上usb接口就行,但是一般还不能直接使用,下面将简单说一下如何使用摄像头: 在你的ternimal下输入以下命令: ...

  7. Linux shell基础知识(上)

    Linux shell基础知识(上) 目录 一.shell介绍 二.命令历史 三.命令补全和别名 四.通配符 五.输入输出重定向 六.管道符和作业控制 七.shell变量 八.环境变量配置文件 九.b ...

  8. python自学第7天,函数,参数

    函数:逻辑结构化和过程化的一种编程方法 面向对象--->类 class 面向过程--->过程 def 函数编程--->函数def import time def logger(): ...

  9. 将100道计算题输出至txt文件,再读取文件至控制台,在控制台中输入答案并评判对错

    我在课堂上基本完成了输出100道题和创建文档,但是因为对输入输出流不熟悉,所以并没有实现将输出的计算题导出到文档里,在课下我又请教了宿舍的大佬,基本完成如下: 源代码: import java.io. ...

  10. SpringBoot的学习【3.HelloWorld配置细节】

    /** * @SpringBootApplication用来标注主程序类. */ @SpringBootApplication public class First { public static v ...