9 HashSet HashCode 迭代器 TreeSet Colletions类 HashMap

Wesley13
• 阅读 471

1. 当向ArrayList添加一个对象时,实际上就是将该对象放置到了ArrayList底层所维护的数组当中;当向LinkedList中添加一个对象时,实际上LinkedList内部会生成一个Node对象,该Node对象的结构为:

void linkLast(E e) {
        final Node<E> l = last;
        final Node<E> newNode = new Node<>(l, e, null);
        last = newNode;
        if (l == null)
            first = newNode;
        else
            l.next = newNode;
        size++;
        modCount++;
    }

private static class Node<E> {
        E item;
        Node<E> next;
        Node<E> prev;

        Node(Node<E> prev, E element, Node<E> next) {
            this.item = element;
            this.next = next;
            this.prev = prev;
        }
    }

其中的Object类型的元素element就是我们向LinkedList中所添加的元素,然后Node又构造好了向前与向后的引用previous、next,最后将生成的这个Node对象加入到了链表当中。换句话说,LinkedList中所维护的是一个个的Node对象。

2. 关于Object类的equals方法的特点

a) 自反性:x.equals(x)应该返回true
b) 对称性:x.equals(y)为true,那么y.equals(x)也为true。
c) 传递性:x.equals(y)为 true并且y.equals(z)为true,那么x.equals(z)也应该为true。
d) 一致性:x.equals(y)的第一次调用为true,那么x.equals(y)的第二次、第三次、第n次调用也应该为true,前提条件是在比较之间没有修改x也没有修改y。

e) 对于非空引用x,x.equals(null)返回false。

3. 关于Object类的hashCode()方法的特点:

a) 在Java应用的一次执行过程当中,对于同一个对象的hashCode方法的多次调用,他们应该返回同样的值(前提是该对象的信息没有发生变化)。

b) 对于两个对象来说,如果使用equals方法比较返回true,那么这两个对象的hashCode值一定是相同的。

c) 对于两个对象来说,如果使用equals方法比较返回false,那么这两个对象hashCode值不要求一定不同(可以相同,可以不同),但是如果不同则可以提高应用的性能。

d) 对于Object类来说,不同的Object对象的hashCode值是不同的(Object类的hashCode值表示的是对象的地址)。

4. 当使用HashSet时,hashCode()方法就会得到调用,判断已经存储在集合中的对象的hash code值是否与增加的对象的hash code值一致;如果不一致,直接加进去;如果一致,再进行equals方法的比较,equals方法如果返回true,表示对象已经加进去了,就不会再增加新的对象,否则加进去。

HashSet set = new HashSet();
        
//        set.add(new People("zhangsan"));
//        set.add(new People("lisi"));
//        set.add(new People("zhangsan"));
        
//        People p1 = new People("zhangsan");
//        
//        set.add(p1);
//        set.add(p1);
        
        String s1 = new String("a");
        String s2 = new String("a");
        
        System.out.println("hash code: " + (s1.hashCode() == s2.hashCode()));
        
        set.add(s1);
        set.add(s2);
        
        System.out.println(set)

String的HashCode方法:

/**
     * Returns a hash code for this string. The hash code for a
     * {@code String} object is computed as
     * <blockquote><pre>
     * s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]  String类型的HasCode计算法
     * </pre></blockquote>
     * using {@code int} arithmetic, where {@code s[i]} is the
     * <i>i</i>th character of the string, {@code n} is the length of
     * the string, and {@code ^} indicates exponentiation.
     * (The hash value of the empty string is zero.)
     *
     * @return  a hash code value for this object.
     */
    public int hashCode() {
        int h = hash;
        if (h == 0 && value.length > 0) {
            char val[] = value;

            for (int i = 0; i < value.length; i++) {
                h = 31 * h + val[i];
            }
            hash = h;
        }
        return h;
    }

5. 如果我们重写一个类的equals方法,那么也要重写hashCode方法,反之亦然。

重写HashCode是为了在集合中应用。

Eclipse 自动重写HashCode()和equals();Source->Generate....

迭代器:(类似于GIS里面的cursor)

通常希望循环通过类集中的元素。例如,可能会希望显示每一个元素。到目前为止,处理这个问题的最简单方法是使用iterator,iterator是一个或者实现Iterator或者实现ListIterator接口的对象。Iterator可以完成循环通过类集,从而获得或删除元素。ListIterator扩展Iterator,允许双向遍历列表,并可以修改单元.

**在通过迭代函数访问类集之前,必须得到一个迭代函数。每一个Collection类都提供一个iterator()函数,该函数返回一个对类集头的迭代函数。通过使用这个迭代函数对象,可以访问类集中的每一个元素,一次一个元素。通常,使用迭代函数循环通过类集的内容,步骤如下
–1. 通过调用类集的iterator( )方法获得对类集头的迭代函数。
–2. 建立一个调用hasNext( )方法的循环,只要hasNext( )返回true,就进行循环迭代。
–3. 在循环内部,通过调用next( )方法来得到每一个元素
**

public static void main(String[] args)
    {
        HashSet hash = new HashSet();
        hash.add("I");
        hash.add(" Miss ");
        hash.add(" You ");
        hash.add(" WangBingJia");
        Iterator iterator = hash.iterator();
        while (iterator.hasNext())
        {
            System.out.println(iterator.next().toString());
        }
    }

TreeSet 有顺序的集合,使用前通常需要定义 Comparator,即实现Comparator接口中Compare方法

public class TreeSetTest
{
    
    public static void main(String[] args)
    {
        Compare compare=new Compare();
        TreeSet ts=new TreeSet(compare);
        ts.add((new Student(10)));
        ts.add(new Student(20));
        System.out.println(ts);
        
    }
    

}
class Compare implements Comparator
{

    @Override
    public int compare(Object o1, Object o2)
    {
        // TODO Auto-generated method stub
        Student s1=(Student) o1;
        Student s2=(Student) o2;
        if (s1 .socore<s2.socore)
        {
            return -1;
        }
        else if (s1 .socore==s2.socore)
        {
            return 0;
        }
        else {
            return 1;
        }
        
    }
    }
class Student
{
     int socore;
    Student(int socore){
        this.socore=socore;
    }
    @Override
    public String toString()
    {
        // TODO Auto-generated method stub
        return Integer.toString(socore);
    }
    }

Collections类的一些静态方法

reverseOrder() 反序排列

shuffle  打乱顺序

public static void main(String[] args)
    {
        LinkedList list = new LinkedList();
        
        list.add(new Integer(-8));
        list.add(new Integer(20));
        list.add(new Integer(-20));
        list.add(new Integer(8));
        
        Comparator r = Collections.reverseOrder();
        
        Collections.sort(list, r);
        
        for(Iterator iter = list.iterator(); iter.hasNext();)
        {
            System.out.println(iter.next() + " ");
        }
        
        System.out.println();
        
        Collections.shuffle(list);
        
        for(Iterator iter = list.iterator(); iter.hasNext();)
        {
            System.out.println(iter.next() + " ");
        }
        
        System.out.println("minimum value: " + Collections.min(list));
        System.out.println("maximum value: " + Collections.max(list));
    }

6. Map(映射):实现类HashMap

Map的keySet()方法会返回key的集合,因为Map的键是不能重复的,因此keySet()方法的返回类型是Set;而Map的值是可以重复的,因此values()方法的返回类型是Collection,可以容纳重复的元素。

HashMap hashMap=new HashMap();
hashMap.put("a","Bingjia");
hashMap.put("a","I");
hashMap.put("b","Bingjia");
System.out.println(hashMap);

通过hashMap的KeySet方法,实现对hashMap的遍历

Set set=hMap.keySet();
        Iterator iterator=set.iterator();
        while (iterator.hasNext())
        {
            System.out.println(hMap.get(iterator.next()));
            
        }

HashMap中储存的是一个一个Map.Entry对象,每一个Map.Entry维护了一对key和value

所以对HashMap的遍历可以遍历取出Map.Entry

hMap.put("1","I");
        hMap.put("2","Miss");
        hMap.put("3","You");
        hMap.put("4","WangBingjia");
        
        
        Set set =hMap.entrySet();
        Iterator iterator=set.iterator();
        while (iterator.hasNext())
        {
            Map.Entry entry=(Entry) iterator.next();
            System.out.println("key "+entry.getKey()+" values "+ entry.getValue());
            
        }

利用hashMap统计数字

HashMap hMap=new HashMap();
for(int i=0;i<args.length;i++)
{
if (hMap.containsKey(args[i]))
{
Object o1= hMap.get(args[i]);
Integer integer=(Integer )o1;
integer ++;
hMap.put(args[i],integer);

}
else {
hMap.put(args[i],1);
}
}
System.out.println(hMap);

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Karen110 Karen110
2年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
2年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
10 HashSet HashMap源码 Properties
2HashSet底层是使用HashMap实现的。当使用add方法将对象添加到Set当中时,实际上是将该对象作为底层所维护的Map对象的key,而value则都是同一个Object对象(该对象我们用不上);3\.HashMap底层维护一个Node数组,我们向HashMap中所放置的对象实际上是存储在该数组当中;HashMap中的Pu
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这