首页 文章 精选 留言 我的

精选列表

搜索[java],共10000篇文章
优秀的个人博客,低调大师

Java 面向对象 之 引用传递

http://www.verejava.com/?id=16992763271038 /** 知识点内容: 引用传递 1. 方法参数引用传递 2. 对象与对象之间的引用传递 3. this指针 本对象引用传递 */ public class Refenrence { public static void main(String[] args) { //实例化 工具类 Utils Utils utils = new Utils(); //定义一个计数器个变量 int count = 1; System.out.println(count); utils.increment(count); System.out.println(count); //定义一个计数器数组变量 int[] counts = { 1 }; System.out.println(counts[0]); utils.increment(counts); System.out.println(counts[0]); //定义一个计数器类变量 Count value = new Count(); value.setValue(1); System.out.println(value.getValue()); utils.increment(value); System.out.println(value.getValue()); } } //建一个工具类 class Utils { public void increment(int count) { count++; } public void increment(int[] counts) { counts[0]++; } public void increment(Count count) { count.setValue(count.getValue() + 1); } } class Count { private int value; public int getValue() { return this.value; } public void setValue(int value) { this.value = value; } } http://www.verejava.com/?id=16992763271038

优秀的个人博客,低调大师

Java 面向对象 之 封装方法

http://www.verejava.com/?id=16992728331734 /** 测试类的封装特性 类的封装特性就是, 将类的属性私有化private 然后提供公有的方法去访问 */ public class Encapsulation { public static void main(String[] args) { //实例化Person 类 //1. 引用对象不能访问类的私有属性 //2. 如果要访问私有属性, 一般类中要另外提供访问私有属性的公有方法 Person p = new Person(); //p.name="李明"; //p.age=22; p.setName("李明"); p.setAge(22); p.say(); System.out.println(p); System.out.println(p.getName() + " " + p.getAge()); } } class Person { //实现类属性的封装 前面加 private 关键字 private String name; private int age; //定义访问私有属性的公有方法 //括号中 String name 是 方法setName 的传入参数 public void setName(String name) { //this 代表当前对象的引用, 哪个对象引用该类,就是指的哪个引用 System.out.println(this); this.name = name; } //String 是方法getName 的返回值的类型 输出返回值 public String getName() { return this.name; } public void setAge(int age) { this.age = age; } public int getAge() { return this.age; } public void say() { System.out.println("我的名字叫:" + name + ",今年 " + age + " 岁"); } } /* 回顾总结 1. 在类当中定义的变量叫成员变量, 属性就是成员变量, 可以在整个类当中访问 2. 在方法中定义的变量叫局部变量, 只能在定义的方法当中访问 注意: 当局部变量和成员变量同名的时候, 局部变量回覆盖掉成员变量,所以当两个变量同名时 要区分成员变量必须加上 this */ http://www.verejava.com/?id=16992728331734

优秀的个人博客,低调大师

Java 目录和文件的复制

1.复制一个目录及其子目录、文件到另外一个目录 //复制一个目录及其子目录、文件到另外一个目录 public void copyFolder(File src, File dest) throws IOException { if (src.isDirectory()) { if (!dest.exists()) { dest.mkdir(); } String files[] = src.list(); for (String file : files) { File srcFile = new File(src, file); File destFile = new File(dest, file); // 递归复制 copyFolder(srcFile, destFile); } } else { InputStream in = new FileInputStream(src); OutputStream out = new FileOutputStream(dest); byte[] buffer = new byte[1024]; int length; while ((length = in.read(buffer)) > 0) { out.write(buffer, 0, length); } in.close(); out.close(); } } private void copyFolder(File src, File dest) throws IOException { if (src.isDirectory()) { if (!dest.exists()) { dest.mkdir(); } String files[] = src.list(); for (String file : files) { File srcFile = new File(src, file); File destFile = new File(dest, file); // 递归复制 copyFolder(srcFile, destFile); } } else { InputStream in = new FileInputStream(src); OutputStream out = new FileOutputStream(dest); byte[] buffer = new byte[ 1024]; int length; while ((length = in.read(buffer)) > 0) { out.write(buffer, 0, length); } in.close(); out.close(); } }

优秀的个人博客,低调大师

Java----------LeetCode----------46. 全排列

说起回溯算法,渊源颇深,我上次做过一道,本应该这次能拿下但是,又没拿下,不过这次有点理解它的思想了, 每次的回溯就是一个二叉树,简单的说,就是你执行的操作需要回溯时它会返回调用它的方法哪里的状态,进行下一步的执行。 public List<List<Integer>> permute(int[] nums) { List<List<Integer>> temp = new ArrayList<>(20); zuhe(temp,0,nums); return temp; } private void zuhe(List<List<Integer>> temp, int n, int[] nums) { /* * 每次让其加一个就行了,就空了, * */ if (nums.length == n) { List<Integer> integers =new ArrayList<>(20); for (int r:nums){ integers.add(r); } temp.add(integers); } for (int i = n, length = nums.length; i <length ; i++) { change(nums,i,n); zuhe(temp,n+1,nums); change(nums,i,n); } } public void change(int[] nums, int i, int j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } 这个需要多练,具体自己体会

优秀的个人博客,低调大师

java之 ------------[LeetCode] House Robber 打家劫舍||

做完打家劫舍后我发现自己动态规划方面处理问题的能力,终于迎来了开篇,虽然打家劫舍是在我看网上的别的人做的,然后自己理解的,但是我知道我再遇到这类题不会再手足无措了,隔了两天再来挑战,我看看自己的动态规划能力是否有那么一点点,于是做了打家劫舍||,虽然我做了将近2个小时,但是庆幸的是自己依靠自己的能力做了出来,很感动,自己花了一晚上的时间做出来了,我都被自己感动的哭了,我算法如此垃圾,竟然能完全依靠自己的能力做出这个算法,真的很让我相信:天才是少数的,大多数人喜欢给自己的懒,找借口。好了不说, 说思路吧: 1.不让它收尾都取,只让它取其一,首端取了,尾端就不取,尾端取了首端就不取,然后在打家劫舍的基础上多声明一个数组,这个数组的取值是从原数组的尾端开始取值的,其实算法和打家劫舍一样,只不过我把打家劫舍的算法用了两遍, 2.上代码吧 public int rob(int[] nums) { if (nums.length == 0) { return 0; } if (nums.length == 1) { return nums[0]; } int max = Math.max(nums[0],nums[1]); if (nums.length == 2) { return max; } int[] f = new int[nums.length]; int[] n = new int[nums.length]; f[0] = nums[0]; f[1] = max; n[nums.length-1] = nums[nums.length-1]; n[nums.length-2] = Math.max(nums[nums.length-1],nums[nums.length-2]); for (int i = 2; i <nums.length-1 ; i++) { f[i] = Math.max(f[i - 2] + nums[i], f[i - 1]); } for (int i = nums.length-3; i > 0; i--) { n[i] = Math.max(n[i+2] + nums[i], n[i+1]); } if (f[nums.length-2] >= n[1]){ return f[nums.length-2]; } return n[1]; }

优秀的个人博客,低调大师

Java 数组 之 一维数组

http://www.verejava.com/?id=16992640551624 /** 数组分类 1. 一维数组 1.1 一维数组的定义和初始化 1.2 对一维数组的操作, 遍历,添加,插入,修改,删除,排序,查找 2. 二维数组 2.1 二维数组的定义和初始化 2.2 二维数组的遍历 3. 多维数组 4. 增强for循环 */ public class Array { public static void main(String[] args) { //一维数组的定义和初始化 //静态定义一维数组 int[] scores = { 90, 70, 50, 80, 60, 85 }; //动态定义一维数组 int[] arr = new int[6]; arr[0] = 90; arr[1] = 70; arr[2] = 50; arr[3] = 80; arr[4] = 60; arr[5] = 85; //一维数组遍历,打印出数组scores的成绩 for (int i = 0; i < scores.length; i++) { System.out.print(scores[i] + ","); } } } //数组为字符串1 public class Test1 { public static void main(String[] args) { // 书架上放了一组图书, 打印出这组图书的书名 //创建一个存放书的书架, 定义一个空的存放书的数组 0,1,2,3 String[] books = new String[4]; // 4是数组的长度 //将书存入数组 books books[0] = "乔布斯传"; books[1] = "从优秀到卓越"; books[2] = "人生不设限"; books[3] = "态度决定一切"; //打印出这组图书的书名 //System.out.println(books[2]); //数组的遍历 System.out.println(books.length); //数组的元素个数 for (int i = 0; i < books.length; i++) { System.out.println(books[i]); } } } //数组为字符串 2 public class Test2 { public static void main(String[] args) { //定义一个初始化的数组 int a = 0; String[] books = { "乔布斯传", "从优秀到卓越", "人生不设限", "态度决定一切" }; for (int i = 0; i < books.length; i++) { System.out.println(books[i]); } //王涛中考 考了 语文 ,数学,英语 分别为 90, 95, 100 int[] scores = { 90, 95, 100 }; for (int i = 0; i < scores.length; i++) { System.out.println(scores[i]); } } } http://www.verejava.com/?id=16992640551624

优秀的个人博客,低调大师

java之 ------------[LeetCode] House Robber 打家劫舍

刚开始做这一道题感觉卧槽,这不简单吗,直接去把数组下标和2取余的数相加再把剩下的数相加,比较这两个和谁大就输出谁,不就行了,但是啊,我操,事实证明,我还是太天真了,我操出现[2,1,1,2]这种情况,我当时还怀疑为什么那么简单后来一想,我操,这不是动态规划吗,于是乎,恶补一下怎么实现动态规划的,说白了,动态规划就是把大的数据拆成小的数据,如我想计算f(10),我就要计算出f(9)+1,然后我想计算出f(9)=f(8)+1,递推的方式直到f(1)=f(0)+1,就结束了。就是上面的结果依赖与下边的结果。 /* 注意这里的返回值,你一定在疑惑为什么返回值,返回的是arry.length-1,那是因为我刚开始计算的时候 * 就涉及到前三个数字,如果返回arry.length,那么会报越界异常。 * 其实啊,说白了,就是【表情】那个对一个数组的递推,只不过借助一个空的数组来实现 * 前期给【表情】【表情】这个空的数组赋初值,这里是两个,借助的这个数组就前两个是有值的,其它没值 * */ public int leastPath(int[] arry) { int length = arry.length; // 声明一个空的数组,就是为了递推做准备 int[] another = new int[arry.length]; if (length == 0) { return 0; } if (length == 1) { return arry[0]; } int many = Math.max(arry[0],arry[1]); if (length == 2) { return many; } // 设置要进行递推的初值 another[0] = arry[0]; another[1] = many; // 注意这里的another.length,的设置,注意长度和下标的区别 for (int i = 2; i <another.length ; i++) { // 这是最核心的代码,当你计算出第一步递推,后边就简单了 another[i] = Math.max(another[i-2]+arry[i],arry[i-1]); } return another[arry.length-1]; }

优秀的个人博客,低调大师

Java 基础 之 continue和 break

http://www.verejava.com/?id=17159306674727 public class Test2 { public static void main(String[] args) { for (int i = 1; i <= 64; i++) { //如果 i==13 当前循环不执行, 继续执行后面的循环 if (i == 13) { continue; //终止当前循环, 继续后面的循环 } if (i == 20) { break; //终止退出循环, 后面的循环不会再执行 } System.out.print("*" + i); if (i % 8 == 0) { System.out.println(""); } } } } http://www.verejava.com/?id=17159306674727

优秀的个人博客,低调大师

Java并发编程LockSupport使用实例

最近负责的项目需要实现一个Web页面监控功能,待监控的数据需要从数据库中统计出来。本身来讲这是一个很简单的功能点,但是考虑到监控端页面会被多人同时访问的业务场景,监控数据又要求每间隔一秒刷新一次,如果每个监控界面都实时去访问数据库,那么数据库的资源开销就太大了,若在白天的业务繁忙期遇到监控端用户数较多时有可能会影响正常的交易办理。为了避免数据库资源过度使用的问题我的设计是在web容器后台构建一块监控数据缓存,无论前台有多少个人访问监控页面,都只是从web容器缓存中获取监控数据,web容器后台有一个值守线程X每间隔一秒访问数据库轮询监控数据至内存中,示意图如下: 屏幕快照 2018-07-27 下午4.50.43.png 仅仅实现以上业务流程其实也非常简单,还用不上LockSupport支持,但是本着对系统资源的最低能耗及高性能需求,我有了更进一步的优雅实现愿景,当没有User监控请求访问容器时后台值守线程可以不干活让其处于阻塞状态,当容器收到User端监控请求时后台值守线程X立即从阻塞状态转变成Running状态,为此我们需要学习运用concurrent包中的LockSupport类来控制多线程间的运行状态切换以实现需求 LockSupport学习 LockSupport是JDK中比较底层的类,用来创建锁和其他同步工具类的基本线程阻塞原语。LockSupport很类似于二元信号量(只有1个许可证可供使用),如果这个许可还没有被占用,当前线程获取许可并继续执行;如果许可已经被占用,当前线程阻塞,等待获取许可。通过网上一些对LockSupport的源码分析可知,其实现是通过调用本地代码(C++)来做的,具有很强的OS平台相关性,因此性能应该是非常高的。对于JVM应用来说主要是通过调用LockSupport.park()和LockSupport.unpark()实现线程的阻塞和唤醒操作的,当然实现线程间的阻塞和唤醒我们还可以用到对象锁,通过Synchronizer关键字来实现对象同步锁,使用对象的wait()和notify()方法来实现,但是此方式的实现在性能上会大打折扣而且有些并发控制不当非常容易引发线程间死锁,可以说非常不优雅。 LockSupport类核心方法 基于Unsafe类中的park和unpark方法 public static void park() { UNSAFE.park(false, 0L); } public static void unpark(Thread thread) { if (thread != null) UNSAFE.unpark(thread); } park()方法,调用native方法阻塞当前线程 unpark()方法,唤醒处于阻塞状态的线程Thrread LockSupport类测试Demo 如下编写一个ThreadPark类来验证park与unpark方法的成对使用 public class ThreadParkTest { public static void main(String[] args) { MyThread mt = new MyThread(); mt.setName("mt"); mt.start(); try { Thread.currentThread().sleep(10); mt.park(); Thread.currentThread().sleep(10000); mt.unPark(); Thread.currentThread().sleep(10000); mt.park(); } catch (InterruptedException e) { e.printStackTrace(); } } static class MyThread extends Thread { private boolean isPark = false; public void run() { System.out.println(" Enter Thread running....."); while (true) { if (isPark) { System.out.println(Thread.currentThread().getName()+"Thread is Park....."); LockSupport.park(); } //do something System.out.println(Thread.currentThread().getName()+">> is running"); try { Thread.currentThread().sleep(1000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public void park() { isPark = true; } public void unPark() { isPark = false; LockSupport.unpark(this); System.out.println("Thread is unpark....."); } } } 程序运行输出: Enter Thread running..... mt>> is running mt>> is running mt>> is running mt>> is running mt>> is running mtThread is Park..... Thread is unpark..... mt>> is running mt>> is running mt>> is running mt>> is running mt>> is running mt>> is running mt>> is running mt>> is running mt>> is running mt>> is running mtThread is Park park翻译过来即是停车的意思,我们可以这样理解,每个被应用程序启动的线程就是一辆在计算机总线赛道上奔驰着的跑车,当你想让某台车停下来休息会时那么就给它一个park信号,它就会立即停到赛道旁边的停车位中,当你想让它从停车位中驶出并继续在赛道上奔跑时再给它一个unpark信号即可 LockSupport的业务实际应用 我们对技术基础知识的掌握是为了更好,更优雅,更从容的实现业务需求,以最小的程序代价来实现业务最大收益化是计算机软件工程的永恒追求主题之一。 差不多给自己埋好坑了(围笑),不扯淡了,还是show me the code吧。 回到第一章的监控业务需求,首先我们需要编写后台值守线程X类,Daemon线程类Run()方法中除实现从数据库中加载监控数据到内存之外还必须实现具备满足一定条件时调用park()方法线程自动停车,同时对外要提供unpack()方法用于外部唤醒线程。 后台值守线程MonitorWorkThread类代码编写: class MonitorWorkThread extends Thread { //当前线程停车标志 private volatile boolean isPark = false; //工作线程默认一秒钟加载一次,count即为工作监控线程每一次unpack之后会继续工作的时间,此值可根据实际需求配置化 private int maxWorkCount = 300; @Override public void run() { int indexCount=0; logger.info("成功启动审核任务监控工作线程,当前工作线程每次unpack连续工作的时间设定为"+maxWorkCount+"秒"); while(true) { if(indexCount >= maxWorkCount) { logger.info("当前监控工作线程已到达连续工作时间设定上限,现在进入pack休眠状态"); isPark =true; indexCount=0; LockSupport.park(); } //从数据库中加载数据至内存 try { loadDataFromDB(); } catch (Exception e1) { logger.warn("从数据库中加载监控数据至内存发生异常", e1); } try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { logger.warn("工作线程被异常中断唤醒", e); } indexCount++; } } /** * 假如当前线程正在运行状态,donothing */ public void unPack() { if(isPark) { //唤醒当前监控工作线程,此处有并发唤醒动作需加锁 synchronized (this) { isPark = false; LockSupport.unpark(this); logger.info("当前监控工作线程已被唤醒"); } } } } 接下来我们考虑编写监控业务实现类,大体思路是我们先需要定义内存缓存map用于装载数据库监控数据,业务实现类在容器实例化时自动启动上面的值守线程MonitorWorkThread,对外提供一个获取内存数据的公共方法,公共方法体中需要调用值守线程的unPack()方法以实现当容器收到客户端监控访问请求时若后台异步值守线程处于停车(阻塞)状态时,会被唤醒继续奔跑上路。任务监控业务实现类TaskMonitorServiceImpl编写: /** * * @author lyp * 审核任务监控实现类 */ @Service("TaskMonitorServiceImpl") public class TaskMonitorServiceImpl { private static Logger logger= Logger.getLogger(TaskMonitorServiceImpl.class); //总任务状态缓存表 private List<TaskStatusBean> totalStatus = new ArrayList<TaskStatusBean>(); //审核柜员任务处理缓存表 private Map<String,UserTaskCountDto> userTaskMap = new ConcurrentHashMap<String, UserTaskCountDto>(); //监控工作线程引用 private static MonitorWorkThread workThread=null; @PostConstruct private void initalizal() { //实例化之后执行的初始化动作,用于启动值守监控线程来刷新加载数据 workThread = new MonitorWorkThread(); workThread.setDaemon(true); workThread.setName("AuthTaskMonitor"); workThread.start(); } /** * 此为对外提供方法用于外部根据监控用户号获取内存中缓存的监控数据 * @param userno 监控用户号 * @return map key1:totalStatus key2:userno * @throws Exception */ public Map<String,Object> monitorDataByUser(String userno) throws Exception { if(null == userno || "".equals(userno)) { return null; } Map<String,Object> retMap = new HashMap<String, Object>(); if(null !=workThread) { //每次请求都去看看异步值守线程是否需求唤醒 workThread.unPack(); } retMap.put("totalStatus", totalStatus); if(userTaskMap.containsKey(userno)) { retMap.put(userno, userTaskMap.get(userno)); }else { UserTaskCountDto dto = new UserTaskCountDto(userno); retMap.put(userno, dto); } return retMap; } /** * 从数据库中加载内存数据至内存 */ private void loadDataFromDB () throws Exception { logger.info("开始从数据库中加载任务监控数据..."); //do something about business.... logger.info("从数据库中加载任务监控数据完毕..."); } /** * 清理监控缓存数据map */ public void clearMonitorCache() { this.totalStatus.clear(); this.userTaskMap.clear(); } } 写在最后 技术知识的学习本身就是枯燥无味的,靠解决问题的动力来驱动技术知识的掌握未尝不是一个值得尝试的高效学习方法。以上是我第一次在简书书写文章,选择加入简书的原因其实很简单,一是看美剧的时候被大量广告植入,二是简书的编辑器完美支持MarkDown语言写作。其实这也是我第一次使用MarkDown标记语言写作排版,MarkDown的写作方式对于程序员来说真的是太爽了,啊啊啊。MarkDown语言 Markdown is intended to be as easy-to-read and easy-to-write as is feasible. Readability, however, is emphasized above all else. A Markdown-formatted document should be publishable as-is, as plain text, without looking like it's been marked up with tags or formatting instructions. Markdown's syntax is intended for one purpose: to be used as a format for writing for the web 写作不易,看完本文如果你觉得对你的工作生活有帮助请给个赞赏,不在乎多少,这会给予我写作无限的动力。 最后如果你需要转载此文,请标明原创出处,谢谢。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册