当前位置: 首页 > article >正文

Java对象的创建方式以及对象的引用

日子就是这么的庸常,却有细碎的事物,如太阳碎碎的光芒,洒落其上
在这里插入图片描述

Java创建对象有几种方式

new创建新对象

new创建我们就很熟悉了,像Person p = new Person();等等

通过反射机制

这种创建对象的方式就是当我们编译时不知道要创建什么对象时,只有在运行时才能确定,这个时候就可以通过反射来创建对象

采用clone机制

clone复制机制一般分为浅拷贝和深拷贝

  • 浅克隆:原对象和克隆对象不同,但对象内的成员引用相同

  • 深克隆:原对象和克隆对象不同,且对象内的成员引用也不同

    不同:不是同一个对象,所占内存地址不同

    成员引用:类中为引用类型的成员

通过序列化机制

“序列化”是一种把对象的状态转化成字节流的机制,“反序列”是其相反的过程,把序列化成的字节流用来在内存中重新创建一个实际的Java对象。这个机制被用来“持久化”对象。通过对象序列化,可以方便的实现对象的持久化储存以及在网络上的传输

Java对象的引用----强软弱虚

  • 强引用

    强引用是平常中使用最多的引用,强引用在程序内存不足(OOM)的时候也不会被回收,使用方式:

    String str = new String("str");
    System.out.println(str) // str
    
  • 软引用

    软引用在程序内存不足时,会被回收,使用方式:

    // 注意:wrf这个引用也是强引用,他是指向SoftReference这个对象的
    // 这里的软引用指的是指向new String("str")的引用,也就是SoftReference类中的T
    SoftReference<String> wrf = new SoftReference<String>(new String("str"));
    

    可用场景:创建缓存的时候,创建的对象放进缓存中,当内存不足时,JVM就会回收早先创建的对象

  • 弱引用

    弱引用就是只要JVM垃圾回收器发现了它,就会回收,使用方式:

    WeakReference<String> wrf = new WeakReference<String>(str);
    

    可用场景: Java源码中的 java.util.WeakHashMap 中的 key 就是使用弱引用,我的理解就是,一旦我不需要某个引用,JVM会自动帮我处理它,这样我就不需要做其它操作。

  • 虚引用

    虚引用的回收机制跟弱引用差不多,但是它被回收之前,会被放入 ReferenceQueue 中。注意 哦,其它引用是被JVM回收后才被传入 ReferenceQueue 中的。由于这个机制,所以虚引用大多 被用于引用销毁前的处理工作。还有就是,虚引用创建的时候,必须带有 ReferenceQueue , 使用例子:

    PhantomReference<String> prf = new PhantomReference<String>
      (new String("str"),new ReferenceQueue<>());
    

    可用场景: 对象销毁前的一些操作,比如说资源释放等。 Object.finalize() 虽然也可以做这 类动作,但是这个方式即不安全又低效

上诉所说的几类引用,都是指对象本身的引用,而不是指Reference的四个子类的引用 (SoftReference等)。

在这里插入图片描述

二分查找

题目:俄罗斯套娃信封问题

难度:🌟🌟🌟🌟🌟

来源:力扣(LeetCode)

链接:https://leetcode.cn/problems/russian-doll-envelopes

给你一个二维整数数组 envelopes ,其中 envelopes[i] = [wi, hi] ,表示第 i 个信封的宽度和高度。

当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。

请计算 最多能有多少个 信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。

注意:不允许旋转信封。

示例 1:

输入:envelopes = [[5,4],[6,4],[6,7],[2,3]]
输出:3
解释:最多信封的个数为 3, 组合为: [2,3] => [5,4] => [6,7]。

示例 2:

输入:envelopes = [[1,1],[1,1],[1,1]]
输出:1

请先思考!!!!

|||||||||||

|||||||||||

|||||||||||

|||||||||||

|||||||||||

|||||||||||

|||||||||||

答答答答答答答答答答答

案案案案案案案案案案案

往往往往往往往往往往往

下下下下下下下下下下下

翻翻翻翻翻翻翻翻翻翻翻

|||||||||||

|||||||||||

|||||||||||

|||||||||||

|||||||||||

|||||||||||

|||||||||||

class Solution {
    public int maxEnvelopes(int[][] envelopes) {
        // 如果我们控制了一列,那么这个问题就会变成找一维数组的最长子序列的问题
        // 加入我们控制宽度w按照省升序的方式排序,如果宽度w相同,那么就将高度h降序排序
        // 排序完就成了 [2,3],[5,4],[6,7],[6,4]
        // 此时我们就可以求高度h的最长子序列就可以找到问题的答案
        // 排序,这个地方采用了Arrays.sort()方法进行自定义排序
         Arrays.sort(envelopes, new Comparator<int[]>() {
            @Override
            public int compare(int[] a, int[] b) {
                // 如果w相同就按照h的降序排序
                return a[0] == b[0] ? b[1] - a[1] : a[0] - b[0];
            }
        });
        // 拍完序之后就h列作为新的数组来求LIS序列
        int[] arr = new int[envelopes.length];
        for( int i = 0 ; i < envelopes.length ; i++){
            arr[i] = envelopes[i][1];
        }
        // 计算LIS的个数
        return arrayLISNum(arr);
    }

    // 求最大的自序列
    public int arrayLISNum(int[] arr){
        int[] maxArr = new int[arr.length];
        int res = 0;
        for(int num : arr){
            int x = 0;
            // y就是代表maxArr数组的长度也就是res也是代表maxArr数组的长度
            int y = res;
            while(x < y){
                int mid = (x + y) >> 1;
                if(maxArr[mid] >= num){
                    y = mid;
                }else {
                   x = mid + 1;
                }
            }
            maxArr[x] = num;
            if(y == res){
                res++;
            }
        }
        return res;
    }
}

题解:

这个问题的难点就在于怎么进行排序来求出LIS序列,一般遇到问题的时候我们就要思考,一维数组我们很好控制,那么能不能将二维数组转换为一维数组来进行判断,首先我们就想到,要想将二维数组的问题转换为一维数组那么我们就要控制好一个纬度,然后操作另一个纬度,在本次俄罗斯套娃问题中就很好的体现,我们控制好宽度或者高度然后去操作高度或者宽度,就可以复杂的问题简单化,具体思路已经在注释上体现了。


http://www.kler.cn/news/17353.html

相关文章:

  • 【Elsevier】中科院2区TOP, 高被引119篇, 稳定检索22年, 1周可见刊,5月15截稿~
  • Simulink 自动代码生成电机控制:弱磁控制从仿真到硬件开发板验证实验
  • 豪取BAT!超详细暑期实习算法面经(非科班无论文)
  • 如何监控一个程序的运行情况,然后视情况将进程杀死并重启
  • redis使用总结
  • 对传递函数的零极点、频率响应、稳定性的理解
  • Vue3 如何全局使用按钮截流指令
  • 复古决战快速施法穿墙秒怪分析流程及安全防护
  • 网络基础设施 拥塞控制
  • 基于JavaWeb实现的寻码网文章资讯管理系统
  • 动态页面配置
  • 我有一个方法判断你有没有编程天赋
  • ElasticSearch学习随笔之分词算法
  • 第17章 信息系统安全管理
  • IAST工具是如何工作的?主动和被动IAST有什么区别?
  • 信号完整性分析基础知识之传输线和反射(三):仿真和测试反射波形
  • 开放式基金净值估算数据 API 数据接口
  • 编写服务器重启的脚本(rc.local调用版本)
  • 基于GWO灰狼优化算法的城市路径优化问题GWO-TSP(MATLAB程序)
  • 操作系统——线程调度
  • SpringBoot整合Mybatis-Plus、Jwt实现登录token设置
  • Java回收垃圾的基本过程与常用算法
  • 面试总结,4年经验
  • python语法入门到面向过程编程(二)
  • 类与对象之构造函数
  • SPSS如何进行基本统计分析之案例实训?
  • 什么是工业互联网?5G到底能在工业互联网中承担哪些重任呢?
  • Java实现添加文字水印、图片水印功能
  • java基础知识——27.动态代理
  • Linux指令大全——从零入门到实用工具