4.3-4.4学习总结

文章目录

一、Java集合

1.集合的概念

Java集合类是一种特别有用的工具类 , 可用于存贮数量不等的对象 , 并可以实现经常用的数据结构 , 同时集合还可用于保存具有映射关系的关联数组.

Java集合大致可分为Set   List    Queue   Map四种体系

  • Set ( 无序 不可重复的集合 )
  • List ( 代表有序 , 重复的集合 )
  • Map ( 代表具有映射关系的集合 )
  • Queue ( 队列集合 )

Java 集合就像一种容器 , 可以把多个对象 ( 实际上是对象的引用 , 但习惯上都成对象 ) " 丢进 "该容器中 .

 Java集合类的作用 : 

  • 保存数量不确定的数据
  • 保存具有映射关系的数据 ( 也被称为关联数组 )

集合类主要负责保存 , 盛装其他数据 , 因此集合类也被称为容器类 .

集合里只能保存对象 ( 实际上只是保存对象的引用变量 , 但通常习惯上认为集合里保存的是对象 )

Java的集合类主要有两个接口派生而出 : Collection 和 Map

牢记: 

集合类就像容器 , 现实生活中容器的功能 , 无非就是添加对象 , 删除对象, 清空容器 , 判断容器是否为空等 , 集合类就为这些功能提供了对应的方法. 

package name;

import java.util.ArrayList;
import java.util.HashSet;

public class CollectionTest {
    public static void main(String[] args)
    {
        ArrayList a = new ArrayList();
        a.add("孙悟空");
        a.add(6);
        System.out.println("a集合里面的元素个数为: " + a.size());
        System.out.println("a集合是否包含\"孙悟空\"字符串: " + a.contains("孙悟空"));
        a.add("轻量级Java EE企业应用实战.");
        System.out.println("a集合的元素: " + a);
        HashSet books = new HashSet();
        books.add("轻量级Java EE企业应用实战.");
        books.add("疯狂Java讲义");
        System.out.println("a的集合里面是否完全包含books集合?" + a.containsAll(books));
        a.removeAll(books);
        System.out.println("a集合里面的元素: " + a);
        a.clear();
        System.out.println("a集合里面的元素: " + a);
        books.retainAll(a);
        System.out.println("books集合的元素: " + books);
    }
}
a集合里面的元素个数为: 2
a集合是否包含"孙悟空"字符串: true
a集合的元素: [孙悟空, 6, 轻量级Java EE企业应用实战.]
a的集合里面是否完全包含books集合?false
a集合里面的元素: [孙悟空, 6]
a集合里面的元素: []
books集合的元素: []

 2.Set集合

Set 集合类似一个管子 , 程序可以一次把多个对象"丢进" Set集合 , 而Set集合通常不能记住元素的添加顺序 . 

Set集合不允许包含相同的元素 , 如果试图把两个相同的元素加入同一个 Set集合中 , 添加操作会失败 , 新元素不会被加入 .

1.HashSet类

HashSet的特点

  • 不能保证元素的排列顺序 , 顺序可能与添加顺序不同 , 顺序也有可能发生变化
  • HashSet不是同步的 
  • 集合元素值可以是null 

 HashSet存储是通过调用对象的HashCode()方法来得到对象的 hashCode 值 , 然后根据 hashCode 值来决定对象在 HashSet 中的存储位置

package name;

import java.util.HashSet;

public class HashSetTest {
    public static void main(String [] args)
    {
        HashSet books = new HashSet();
        books.add(new A());
        books.add(new A());
        books.add(new B());
        books.add(new C());
        books.add(new C());
        System.out.println(books);
    }

}
class A
{
    public boolean equals(Object obj)
    {
        return true;
    }
}
class B
{
    public int hashCode()
    {
        return 1;
    }
}
class C
{
    public int hashCode()
    {
        return 2;
    }
    public boolean equals(Object obj)
    {
        return true;
    }
}

//输出:
//[name.B@1, name.C@2, name.A@7d4991ad, name.A@4aa298b7]
由上面的两个A对象通过equals方法和地址可见 , 尽管两个A对象返回的都是true
但是Hashset依旧把两个当做不同的对象
由两个 B 对象的返回值都是 1 但地址不同可见 , HashSet依旧是把两个 B 对象
当成不同的对象

这个现象是违背了 Set 的集合的规则的
所以 , 把一个对象放进 HashSet 中, 如果要重写该对象的对应类的 equals()方法,
也应该重写 hashCode()方法

规则是:
如果两个对象通过 equals()都返回true, 则这两个对象的 hashCode也应该要一致

HashCode() 方法规则:

  • 同一个对象多次调用 hashCode() 应该返回相同的值
  • 当两个对象通过equals() 方法比较返回 true 时 , 这两个对象的 hashCode() 方法应该返回相等的值
  • 对象中用作equals()方法比较标准的实例变量 , 都应该用于计算 hashCode值

当向HashSet添加可变对象时 , 必须十分小心 .如果修改HashSet集合中的对象 , 有可能导致该对象与集合中的其他对象相等 , 从而导致 HashSet 无法准确访问该对象 

 2.LinkedHashSet类

LinkedHashSet 集合也是根据元素的 hashCode值来决定元素的存储位置 , 但它同时使用链表维护元素的次序 , 也就是说 , LinkedHashSet 将会按照元素的添加顺序来访问集合里的元素.

 注意: LinkedHashSet 虽然使用了链表记录集合元素的添加顺序 , 但 LinkedHashSet 依然是 HashSet , 因此他依然不允许集合元素重复

3.TreeSet类

TreeSet 是SortedSet接口的实现类 , TreeSet可以确保集合元素处于排序状态

TreeSet提供很多方法的原因: TreeSet里面的元素是有序的 , 所以增加了访问第一个 , 前一个,后一个 , 最后一个元素的方法 , 并且提供了三个从 TreeSet 中截取子 TreeSet的方法

package name;

import java.util.TreeSet;

public class TreeSetTest {
    public static void main(String [] args)
    {
        TreeSet nums = new TreeSet();
        nums.add(5);
        nums.add(2);
        nums.add(10);
        nums.add(-9);
        System.out.println(nums);
        System.out.println(nums.first());
        System.out.println(nums.last());
        System.out.println(nums.headSet(4));
        System.out.println(nums.tailSet(4));
        System.out.println(nums.subSet(-3,4));
    }
}


/*
输出:
[-9, 2, 5, 10]
-9
10
[-9, 2]
[5, 10]
[2]
 */

  • TreeSet 不是根据元素的插入顺序排序的 , 而是根据元素实际值的大小来进行排序的
  • TreeSet采用红黑树的数据结构来存储集合元素
  • TreeSet 支持两种排序方式 : 自然排序和定制排序 , 默认情况下 , TreeSet采用自然排序 

TreeSet两种功能排序模式: 自然排序和定制排序 

自然排序:TreeSet调用集合的compareTo(Object obj)方法比较元素大小 , 然后将元素升序排列

 Comparable接口:

Java提供了一个Comparable接口 , 该接口里定义了一个 compareTo(Object obj)方法 , 该方法返回一个整数值:

  • 如果两个对象相等 , 则返回0
  • 如果返回一个正整数 , 则 obj1>obj2
  • 如果返回一个负整数 , 则 obj1<obj2
package name;

import java.util.TreeSet;

public class TreeSetTest3 {
    public static void main(String [] args)
    {
        TreeSet ts= new TreeSet();
        ts.add(new R(5));
        ts.add(new R(-3));
        ts.add(new R(9));
        ts.add(new R(-2));
        System.out.println(ts);
        R first = (R) ts.first();
        first.count = 20;
        R last = (R) ts.last();
        last.count = -2;
        System.out.println(ts);
        System.out.println(ts.remove(new R(-2)));
        System.out.println(ts);
        System.out.println(ts.remove(new R(5)));
        System.out.println(ts);
    }

}
class R implements Comparable
{
    int count;
    public R(int count)
    {
        this.count = count;
    }
    public String toString()
    {
        return "R[count: " + count + "]";
    }
    public boolean equals(Object obj)
    {
        if(this==obj)
        {
            return true;
        }
        if(obj!=null&&obj.getClass()==R.class)
        {
            R r = (R) obj;
            return r.count ==this.count;
        }
        return false;
    }
    public int compareTo(Object obj)
    {
        R r = (R) obj;
        return count > r.count?1 : count < r.count ? -1:0;
    }
}

/*
输出:
[R[count: -3], R[count: -2], R[count: 5], R[count: 9]]
[R[count: 20], R[count: -2], R[count: 5], R[count: -2]]
false
[R[count: 20], R[count: -2], R[count: 5], R[count: -2]]
true
[R[count: 20], R[count: -2], R[count: -2]]
 */

  • 如果试图把一个对象添加到TreeSet , 则该对象必须实现 Comparable 接口 ,否则程序会发生 ClassCastException异常
  • 同时 , 将一个元素添加到TreeSet树中 , 要求集合中的其他元素与该元素使用一个类的实例 , 否则也会引发 ClassCastException异常 . 也就是说: 如果希望TreeSet能正常运作 , TreeSet只能添加同一种类型.

 如果向TreeSet 添加一个可变对象 , 并且后面程序修改了该可变对象的实例变量,这将导致它与其他对象的大小顺序发生了改变 , 但是TreeSet 不会再一次调整它们的顺序 , 甚至可能导致TreeSet中保存的这两个对象通过compareTo(Object obj)方法比较返回 0 

为了让程序更加健壮 , 最好不要再次修改 HashSet 和 TreeSet 集合中元素的关键实例变量!! 

 定制排序: 如果要实现定制排序 , 例如降序排序 , 则需要通过 Comparator接口的帮助

Comparator接口:

Java提供了一个Comparable接口 , 该接口里定义了一个int compareTo(T o1, T o2)方法 , 该方法返回一个整数值:

  • 如果两个对象相等 , 则返回0
  • 如果返回一个正整数 , 则 obj1>obj2
  • 如果返回一个负整数 , 则 obj1<obj2

 Comparator是一个函数式接口 , 因此可使用Lambda表达式来代替Comparator 对象

package name;

import java.util.TreeSet;

public class TreeSetTest4 {
    public static void main(String [] args)
    {
        TreeSet ts = new TreeSet((o1,o2)->
        {
            M m1 = (M) o1;
            M m2 = (M) o2;
            return m1.age > m2.age ? -1 : m1.age < m2.age ? 1 : 0;
        });
        ts.add(new M(5));
        ts.add(new M(-3));
        ts.add(new M(9));
        System.out.println(ts);
    }
}
class M
{
    int age;
    public M(int age)
    {
        this.age = age;
    }
    public String toString()
    {
        return "M[age: " + age + "]";
    }

}

/*
输出:
[M[age: 9], M[age: 5], M[age: -3]]

 */
  •  通过Comparator对象来时先TreeSet的定制排序 , 依旧不能像 TreeSet 种添加类型不同的对象 , 否测会引发 ClassCastException异常 ;
  • 定制排序的时候 , TreeSet对集合元素排序不管集合元素本身的大小 , 而是由 Comparator 对象负责集合元素的排序规则;
  • TreeSet判断两个集合相等的标准 : 通过比较两个元素返回了0

4.EnumSet类

  • EnumSet是专门为枚举类设计的集合类
  • EnumSet里面的所有元素都必须指定枚举类型的枚举值 ,并且该枚举类型在创建EnumSet时显式或隐式地指定
  • EnumSet的集合元素也是有序的
  • EnumSet通过枚举值在Enum类的定义顺序来决定集合元素的顺序
  • EnumSet集合不允许加入null元素 , 如故如果试图插入null 元素 , EnumSet将抛出NullPointerException异常

package name;

import java.util.EnumSet;

enum Season
{
    SPRING,SUMMER,FALL,WINTER
}
public class EnumSetTest {
    public static void main(String [] args)
    {
        EnumSet a = EnumSet.allOf(Season.class);
        System.out.println(a);
        EnumSet b= EnumSet.noneOf(Season.class);
        System.out.println(b);
        b.add(Season.WINTER);
        b.add(Season.SPRING);
        System.out.println(b);
        EnumSet c = EnumSet.of(Season.SUMMER,Season.WINTER);
        System.out.println(c);
        EnumSet d = EnumSet.range(Season.SUMMER,Season.WINTER);
        System.out.println(d);
        EnumSet e = EnumSet.complementOf(d);
        System.out.println(e);
    }
}

/*
输出:
[SPRING, SUMMER, FALL, WINTER]
[]
[SPRING, WINTER]
[SUMMER, WINTER]
[SUMMER, FALL, WINTER]
[SPRING]
 */

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. RabbitMQ简介 RabbitMQ是一个开源的消息代理,它实现了高级消息队列协议(AMQP),并且支持多种协议。RabbitMQ支持多种编程语言,包括Java、Python、Ruby、PHP、C#等等。RabbitMQ是一个可靠的、可扩展的、可插拔的并且易于使用的消息代理。 2. RabbitMQ安装 2.1 安装Erlang RabbitMQ是基于Erlang语言开发的,所以在安装RabbitMQ之前需要先安装Erlang。可以到Erlang官网下载最新版的Erlang安装包。 2.2 安装RabbitMQ 下载RabbitMQ安装包,根据操作系统的不同选择对应的安装包进行安装。安装过程中需要选择安装目录、配置文件等。 3. RabbitMQ配置 3.1 配置文件 RabbitMQ的配置文件在安装目录下的/etc/rabbitmq目录中。配置文件可以包含多个节,每个节包含多个键值对。可以通过修改配置文件来修改RabbitMQ的行为。 3.2 用户管理 在RabbitMQ中,需要通过用户进行身份验证才能使用RabbitMQ。可以通过以下命令创建用户: rabbitmqctl add_user username password 可以通过以下命令为用户分配角色: rabbitmqctl set_user_tags username role 其中role可以是以下几种角色之一: - administrator:管理员角色,可以进行所有操作。 - management:管理角色,可以管理RabbitMQ,但是不能进行敏感操作。 - monitoring:监控角色,可以查看RabbitMQ的状态信息。 - policymaker:策略制定者角色,可以制定RabbitMQ的策略。 3.3 虚拟主机 在RabbitMQ中,虚拟主机是一个逻辑概念,它允许在同一个RabbitMQ服务器上创建多个逻辑消息代理。每个虚拟主机有自己的用户、队列、交换机等。可以通过以下命令创建虚拟主机: rabbitmqctl add_vhost vhost_name 可以通过以下命令为虚拟主机分配权限: rabbitmqctl set_permissions -p vhost_name username ".*" ".*" ".*" 其中,第一个.*表示允许用户对虚拟主机中的队列进行所有操作,第二个.*表示允许用户对虚拟主机中的交换机进行所有操作,第三个.*表示允许用户对虚拟主机中的绑定进行所有操作。 4. RabbitMQ使用 4.1 生产者 生产者向RabbitMQ中的队列发送消息。可以使用RabbitMQ提供的客户端库来编写生产者。 4.2 消费者 消费者从RabbitMQ中的队列接收消息。可以使用RabbitMQ提供的客户端库来编写消费者。 4.3 队列 队列是RabbitMQ中最基本的组件,生产者向队列发送消息,消费者从队列接收消息。可以通过RabbitMQ控制台来创建队列。 4.4 交换机 交换机是用来接收生产者发送的消息,并将消息路由到指定的队列中。可以通过RabbitMQ控制台来创建交换机。 4.5 绑定 绑定是将队列和交换机绑定在一起,并指定路由键。可以通过RabbitMQ控制台来创建绑定。 5. 总结 RabbitMQ是一个开源的消息代理,它实现了高级消息队列协议(AMQP),并且支持多种协议。RabbitMQ支持多种编程语言,包括Java、Python、Ruby、PHP、C#等等。RabbitMQ是一个可靠的、可扩展的、可插拔的并且易于使用的消息代理。在使用RabbitMQ时,需要先安装Erlang,然后安装RabbitMQ。可以通过修改配置文件来修改RabbitMQ的行为。在使用RabbitMQ时,需要创建用户、虚拟主机、队列、交换机和绑定等组件。可以使用RabbitMQ提供的客户端库来编写生产者和消费者。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值