Java集合

有时也将集合称为容器类,它的作用就是用来“装对象”的。这里要注意的是集合也可以是对象。下面先看一张图:

HashSet:底层用一个数组存元素 --而且这个数组的长度永远是2的N次方。

HashSet底层就是HashMap实现的。

HashSet的构造器:HashSet(int initialCapacity, float loadFactor)

--initialCapacity:控制底层数组的长度。

如果传入数组长度不是2的N次方,HashSet会自动扩展到2的N次方。

--loadFactory:当HashSet感觉到底层数组快满时,它会再次创建一个长度是原来数组长度2倍的数组。原有的数组就变成垃圾,并且要把原有数组中的元素复制到新数组中,这个过程也叫“重hash”。loadFactory越小,越耗内存;loadFactory越大,性能越低。

举例说明1:

public class Test {

public static void main(String[] args) {

//没有泛型限制的集合

Collection c1 = new HashSet();

c1.add(1);//本来1不是对象,无法装入集合,但由于jdk提供的自动装箱功能,它会将1包装成对象

c1.add(new Date());

//加入泛型限制的集合,意味着该集合只能装“指定类型”的对象。

//jdk1.7可使用"菱形语法"将new HashSet换成new HashSet<>

Collection c2 = new HashSet();

//c2.add(1);错误:只能装String类型的对象

c2.add("张三");

c2.add("李四");

c2.add("王五");

//判断集合是否包含指定元素

System.out.println(c2.contains("张三"));

System.out.println(c2.contains("赵六"));

//遍历Set集合,有两种方式:1)foreach循环,2)迭代器

System.out.print("使用foreach循环遍历:");

for(String e : c2){

System.out.print(e+" ");

}

Iterator it = c2.iterator();

System.out.print("\n使用迭代器遍历:");

while(it.hasNext()){

System.out.print(it.next()+" ");

}

System.out.println();

Collection c3 = new HashSet();

c3.add("张三");

c3.add("王五");

c3.add("赵六");

//求差集c2-c3

//c2.removeAll(c3);

//System.out.println("c2与c3差集:"+c2);

//求并集

//c2.addAll(c3);

//System.out.println("c2与c3并集"+c2);

//求交集

c2.retainAll(c3);

System.out.println("c2与c3交集:"+c2);

}

}

举例说明2:

public class TestHashSet {

public static void main(String[] args) {

HashSet hs = new HashSet(3);//底层数组容量会自动会展到4(注意:2的N次方)

hs.add("1");

hs.add("2");

hs.add("3");

hs.add("4");

hs.add("5");

//当HashSet感觉到底层数组快满时,它会再次创建一个长度是原来数组长度2倍的数组,此时新的数组长度为8

System.out.println(hs);

}

}

HashSet存入机制:

1)当有元素加进来时,HashSet会调用该对象的hashCode()方法,得到一个int值;

2)根据hashCode()返回的int值,计算出它在HashSet的存储位置(数组中的索引);

3)如果要加入的位置是空的,直接方法即可。如果要加入的位置已经有元素,此处就会形成“链表”,数组越满,就越有可能出现链表。

HashSet取元素机制:

1)当有元素加进来时,HashSet会调用该对象的hashCode()方法,得到一个int值;

2)根据hashCode()返回的int值,计算出它在HashSet的存储位置(数组中的索引);

3)如果该位置恰好是要找的元素,直接取出即可。如果该位置有“链表”,HashSet要“挨个”地搜索链表里的元素。

HashSet怎么才会认为两个对象是相等的?(要求自定义类的hashCode()和equals()方法是一致的,即方法中所用到的关键属性要一致)

1、两个对象的hashCode()返回值相等;

2、两个对象通过equals比较返回true。

LinkedHashSet(HashSet的一个子类):它与HashSet的存储机制相似,但LinkedHashSet额外地有一个链表,这个链表可以保证LinkedHashSet能记住元素的添加顺序。

TreeSet(sortedset接口的实现类):它保证Set里添加的元素后是“大小排序”的。底层用一个“红黑树”存放元素。

举例说明(使用TreeSet要求集合元素必须是可以比较大小的):

public class TestTreeSet1 {

public static void main(String[] args) {

TreeSet ts = new TreeSet();

ts.add(3);

ts.add(1);

ts.add(2);

ts.add(5);

ts.add(4);

System.out.println(ts);

}

}

public class TestTreeSet2 {

public static void main(String[] args) {

TreeSet ts = new TreeSet();

ts.add("t");

ts.add("r");

ts.add("e");

ts.add("e");

System.out.println(ts);//字符串的大小

}

}

TreeSet元素存入、检索的性能也比较好。

Java的比较大小有两种方式:

A. --自然排序。所有集合元素要实现Comparable接口。

B. --定制排序。要求创建TreeSet时,提供一个Comparator对象(负责比较元素大小)。

举例说明:

class Apple implements Comparable {

private double weight;// 规定:苹果重量大的苹果越大

public Apple(double weight) {

this.weight = weight;

}

@Override //自然排序

public int compareTo(Apple obj) {

return this.weight > obj.weight ? 1 : this.weight < obj.weight ? -1 : 0;

}

@Override

public String toString() {

return "Apple[weight=" + this.weight + "]";

}

}

public class TreeSetTest {

public static void main(String[] args) {

TreeSet set = new TreeSet();

set.add(new Apple(2.3));

set.add(new Apple(1.2));

set.add(new Apple(3.5));

for (Apple ele : set) {

System.out.println(ele);

}

}

}

class Bird {

private String name;

public String getName() {

return name;

}

public Bird(String name) {

this.name = name;

}

@Override

public String toString() {

return "Bird[name=" + name + "]";

}

}

public class TreeSetTest2 {

public static void main(String[] args) {

// 如果集合元素本身没有实现Comparable接口

// 那就要求创建TreeSet时传入一个Comparator对象

TreeSet set = new TreeSet(new Comparator() {

@Override

public int compare(Bird o1, Bird o2) {

if (o1.getName().compareTo(o2.getName()) > 0) {

return -1;

} else if (o1.getName().compareTo(o2.getName()) < 0) {

return 1;

} else {

return 0;

}

}

});

set.add(new Bird("aabc"));

set.add(new Bird("abc"));

set.add(new Bird("Z"));

set.add(new Bird("dx"));

System.out.println(set);

}

}

ArrayList(JDK1.2)与Vector(JDK1.0,已经过时)都是基于数组实现的,它们的区别如下:

ArrayList(可根据索引来存取元素)是线程不安全的,Vector是线程安全的。

--ArrayList的性能比Vector要好,即使在多线程环境下,可以使用Collections集合工具类的synchronizedXxx方法把ArrayList包装成线程安全的。

而LinkedList底层是基于链表实现的,通常认为它的性能比不上ArrayList,它们的区别如下:

ArrayList:由于可以根据底层数组的索引存取元素,所以性能非常快,但当插入元素、删除元素时性能低。

LinkedList:由于底层采用了链表来存储元素,因此根据索引存取元素性能较慢,但当插入、删除元素时性能非常快。

举例说明:

public class Test {

public static void main(String[] args) {

List list = new ArrayList();

list.add("2");

list.add("1");

list.add("5");

list.add("3");

System.out.println(list);

list.add(2,"在索引2处插入元素");

System.out.println(list);

list.set(2,"在索引2处替换的元素");

System.out.println(list);

list.remove(2);

System.out.println(list);

//遍历list(类似数组)

for(int i =0;i

System.out.print(list.get(i)+" ");

}

}

}

Deque集合:功能被限制的线性表。

//把Deque当成栈用

public class Test {

public static void main(String[] args) {

//把Deque当成栈用

Deque dq = new ArrayDeque();

//进栈(压栈):后进先出

dq.push("a");

dq.push("b");

dq.push("c");

dq.push("d");

//打印首先出栈的元素

System.out.println(dq.pop());

//打印访问栈顶的元素

System.out.println(dq.peek());

}

}

//把Deque当成队列用:先进先出

public class Test2 {

public static void main(String[] args) {

//把Deque当成队列用:先进先出

Deque dq = new ArrayDeque();

//从队列尾部入队

dq.offer("a");

dq.offer("b");

dq.offer("c");

dq.offer("d");

//从队列头部出队

System.out.println(dq.poll());

//打印访问队头元素

System.out.println(dq.peek());

}

}

Collections集合工具类:

public class TestCollections {

public static void main(String[] args) {

List list = new ArrayList();

list.add("a");

list.add("b");

list.add("c");

list.add("d");

System.out.println(list);

//对集合进行反转

Collections.reverse(list);

System.out.println(list);

//把b, c位置进行交换

Collections.swap(list, 1, 2);

System.out.println(list);

//将list集合元素进行随机排列

Collections.shuffle(list);

System.out.println(list);

}

}

结束语

今天内容比较多,而且有些和数据结构相关,所以理解起来可能会有些困难。编程我觉得还是要多练,只要你肯多练,就不会那么难了。今天就讲到这,明天开始讲Map。

java面向对象编程集合边框_Java学习系列(七)Java面向对象之集合框架详解(上)相关推荐

  1. Git学习系列(七)Bug和Feature分支管理详解

    当咱们拿到一个新的bug或者feature(功能)时,首先应该想到通过分支来完成咱们的任务.因为在软件开发中,总是会根据客户的需求不断的添加新的feature进来,同时在做移动开发过程中bug也可以说 ...

  2. java 画笔跟swing组件_Java学习教程(基础)--Java版本历史(二)

    Java语言自JDK1.0版本以来经历了许多次更新,也在基本程序库中增加了大量的类别和包.从J2SE 1.4开始,Java语言的变动由 Java Community Process(JCP)管理,JC ...

  3. java测试类 main方法_Java使用agent实现main方法之前的实例详解

    Java使用agent实现main方法之前的实例详解 创建Agent项目 PreMainExecutor 类,在main方法之前执行此方法 public class PreMainExecutor { ...

  4. java中flush函数作用_Java语言中flush()函数作用及使用方法详解

    最近在学习io流,发现每次都会出现flush()函数,查了一下其作用,起作用主要如下 //------–flush()的作用--------– 笼统且错误的回答: 缓冲区中的数据保存直到缓冲区满后才写 ...

  5. java图片填充父容器_java相关:spring的父子容器及配置详解

    java相关:spring的父子容器及配置详解 发布于 2020-5-26| 复制链接 本篇文章主要介绍了spring的父子容器及配置详解,详细的介绍了spring父子容器的概念.使用场景和用法,有兴 ...

  6. java base64字符 转图片_JAVA实现图片与base64字符串之间的转换详解

    import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import ...

  7. java如何截取视频文件_Java获取视频时长及截取帧截图详解

    前言 只是最近碰到有这方面的项目需求,所以简单 Mark 下本文.下面的示例是参考过他人分享的文章,之后本人再自行实践.调整和测试过的,希望对有这方面需求的人有所帮助. 示例 添加依赖 org.byt ...

  8. java二维数组元素_java二维数组,获取整行元素详解

    之前给大家讲过java二维数组获取单个元素方面的知识,下面的话就来给大家讲一下java二维数组获取整行元素方面的知识. 除去获取单个元素和全部元素之外,还可以单独获取二维数组的某一行中所有元素的值,或 ...

  9. java二维数组添加元素_Java二维数组与动态数组ArrayList类详解

    java二维数组 java 语言中提供的数组是用来存储固定大小的同类型元素. 1.二维数组初始化和声明 数组变量的声明,和创建数组可以用一条语句完成,如下所示: int a[][] = new int ...

最新文章

  1. 小麦带你看postgres(代码模块结构)
  2. javascript计时器_JavaScript计时器:您需要了解的一切
  3. python日志模块为什么打印到界面_如何将外部模块的日志消息打印到主Python模块的终端窗口?...
  4. [多项式算法]多项式求逆 学习笔记
  5. iframe 自适应高度 跨域
  6. LeetCode 1487. 保证文件名唯一(哈希map)
  7. 谷歌浏览器该扩展程序未列在Chrome网上应用店中解决方法
  8. linux挂载ntfs分区报错,Linux下挂载NTFS分区和挂载分区的方法
  9. POJ 3734_Blocks
  10. 【OpenCV】视频输入与相似度测量
  11. 参数修饰符 params、 out、ref
  12. Flask构建微电影(一)
  13. tornado celery mysql_tornado中使用celery实现异步MySQL操作
  14. noip2017提高组初赛(答案+选择题题目+个人分析)
  15. 五种前端布局之table布局
  16. Windows主机操作系统安全加固规范
  17. 虚拟串口VSPD和XCOM的下载+安装+使用
  18. 计算机操作系统的主要功能
  19. 创业者的噩梦 - 该我的钱怎么拿不到?
  20. 哪个计算机无法做到双屏显示,如何实现笔记本电脑的双屏显示

热门文章

  1. python 计算两个日期相差多少个月
  2. 功率谱估计性能分析及matlab仿真,功率谱估计性能分析及Matlab仿真.doc
  3. r读取shape文件可视化_【R】提取 PCA 结果并利用 ggplot2 进行可视化
  4. C语言如何使用其他文件定义的结构体?(C++报错:无法转换到不完整的类【需在头文件中定义结构体??】)
  5. 什么是序列化?python pickle模块
  6. 机器学习中 True Positives(真正例TP)、False Positives(假正例FP)、True Negatives(真负例TN)和 False Negatives(假负例FN)指什么
  7. Leetcode python《热题 HOT 100》1. 两数之和
  8. 半编译半解释的Java语言和C++、Python等语言的区别
  9. 记一次安装docker的坑
  10. linux内核态real cred,Linux内核实验报告——实验5.doc