peek

完整逆波兰计算器(Java)

风格不统一 提交于 2020-08-04 22:08:10
完整逆波兰计算器(Java) 博客说明 文章所涉及的资料来自互联网整理和个人总结,意在于个人学习和经验汇总,如有什么地方侵权,请联系本人删除,谢谢! 功能 支持 + - * / ( ) 多位数,支持小数, 兼容处理, 过滤任何空白字符,包括空格、制表符、换页符 基本思路 中缀表达式转后缀表达式 代码 package stack; import java.util.ArrayList; import java.util.List; import java.util.Stack; import java.util.Collections; import java.util.regex.Pattern; public class ReversePolishMultiCalc { //匹配运算符 static final String SYMBOL = "\\+|-|\\*|/|\\(|\\)"; static final String LEFT = "("; static final String RIGHT = ")"; static final String ADD = "+"; static final String MINUS = "-"; static final String TIMES = "*"; static final String DIVISION = "/"; /

如何解决TOP-K问题

不问归期 提交于 2020-07-29 05:30:31
前言:最近在开发一个功能:动态展示的订单数量排名前10的城市,这是一个典型的Top-k问题,其中k=10,也就是说找到一个集合中的前10名。实际生活中Top-K的问题非常广泛,比如:微博热搜的前100名、抖音直播的小时榜前50名、百度热搜的前10条、博客园点赞最多的blog前10名,等等如何解决这类问题呢?初步的想法是将这个数据集合排序,然后直接取前K个返回。这样解法可以,但是会存在一个问题:排序了很多不需要去排序的数据,时间复杂度过高.假设有数据100万,对这个集合进行排序需要很长的时间,即便使用快速排序,时间复杂度也是O(nlogn),那么这个问题如何解决呢?解决方法就是以空间换时间,使用优先级队列 目录 一: 认识PriorityQueue 二:利用PriorityQueue解决topk问题 三:总结 一:认识PriorityQueue 1.1:PriorityQueue位于java.util包下,继承自Collection,因此它具有集合的属性,并且继承自Queue队列,拥有add/offer/poll/peek等一系列操作元素的能力,它的默认大小是11,底层使用Object[] 来保存元素,数组的话肯定会有扩容,当添加元素的时候大小超过数组的容量,就会扩容,扩容的大小为原数组的大小加上,如果元素的数量小于64,则每次加2,如果大于64,则每次增加一半的容量。 1.2

运用设计模式告别项目中大量臃肿的if else

柔情痞子 提交于 2020-07-28 10:40:42
前言 以前写过的一个老项目中,有这样一个业务场景,比喻:一个外卖系统需要接入多家餐馆,在外卖系统中返回每个餐馆的菜单列表 ,每个餐馆的菜单价格都需要不同的算法计算。 代码中使用了大量的if else嵌套连接,一个类中数千行代码(眼睛快看瞎...),而且随着业务的扩展,接入的餐馆会越来越多,每接入一个餐馆都要增加一个 if else,满屏幕密密麻麻的逻辑代码,毫无可读性。然后前段时间进行了代码重构,使用了策略模式+工厂模式+反射代替了这整片的臃肿代码,瞬间神清气爽。 模拟原业务代码 原代码的简单模拟实现,根据传入的不同餐馆编码获取对应的餐馆类集合,每个餐馆菜单价格的算法都不同。每当需要新接入一家餐馆时,都需要在此增加一个if else,中间加入一大长串的处理逻辑,当餐馆越来越多的时候,代码就变得越来越沉重,维护成本高。 public List server(String hotelCode) { if ("HotelA" .equals(hotelCode)) { // 获取数据 List<HotelA> hotelList = new ArrayList<HotelA> () { { add( new HotelA("爆炒腰子", 100d, 0.8, null )); add( new HotelA("红烧腰子", 200d, 0.8, null )); add( new

Java:Top K问题的解法

随声附和 提交于 2020-07-28 08:49:17
import java.util.Arrays; import java.util.PriorityQueue; import java.util.Queue; public class LeafNode { // 堆方法(优先队列) // 1.堆的性质是每次可以找出最大或最小的元素 // 快排变形 public static void main(String[] args) { int[] arr = new int[] { 1, 2, 34, 4, 5, 6 }; //int[] nums = getLeastNumbers(arr, 3); int[] nums=getLeastNumbersTwo(arr,3); System.out.println(Arrays.toString(nums)); } public static int[] getLeastNumbers(int[] arr, int k) { if (k == 0) return new int[0]; // 使用一个最大堆(大顶堆) Queue<Integer> heap = new PriorityQueue<>(k, (i1, i2) -> Integer.compare(i2, i1)); for (int e : arr) { // 当前数字小于堆顶元素才会入堆 if (heap.isEmpty

java多线程复习与巩固(五)

感情迁移 提交于 2020-07-27 21:56:19
ConcurrentHashMap 并发List Vector和CopyOnWriteArrayList是两个线程安全的List,Vector读写操作都用了同步,相对来说更适用于写多读少的场合,CopyOnWriteArrayList在写的时候会复制一个副本,对副本写,写完用副本替换原值,读的时候不需要同步,适用于写少读多的场合。 并发Set CopyOnWriteArraySet基于CopyOnWriteArrayList来实现的,只是在不允许存在重复的对象这个特性上遍历处理了一下。 并发Map ConcurrentHashMap是专用于高并发的Map实现,内部实现进行了锁分离,get操作是无锁的。 并发的Queue 在并发队列上JDK提供了两套实现,一个是以ConcurrentLinkedQueue为代表的高性能队列,一个是以BlockingQueue接口为代表的阻塞队列。ConcurrentLinkedQueue适用于高并发场景下的队列,通过无锁的方式实现,通常ConcurrentLinkedQueue的性能要优于BlockingQueue。BlockingQueue的典型应用场景是生产者-消费者模式中,如果生产快于消费,生产队列装满时会阻塞,等待消费。 1、offer()和add()的区别 add()和offer()都是向队列中添加一个元素

解读 java 并发队列 BlockingQueue

被刻印的时光 ゝ 提交于 2020-07-26 22:08:59
点击添加图片描述(最多60个字) 编辑 今天呢!灯塔君跟大家讲: 解读 java 并发队列 BlockingQueue 最近得空,想写篇文章好好说说 java 线程池问题,我相信很多人都一知半解的,包括我自己在仔仔细细看源码之前,也有许多的不解,甚至有些地方我一直都没有理解到位。 说到线程池实现,那么就不得不涉及到各种 BlockingQueue 的实现,那么我想就 BlockingQueue 的问题和大家分享分享我了解的一些知识。 本文没有像之前分析 AQS 那样一行一行源码分析了,不过还是把其中最重要和最难理解的代码说了一遍,所以不免篇幅略长。本文涉及到比较多的 Doug Lea 对 BlockingQueue 的设计思想,希望有心的读者真的可以有一些收获,我觉得自己还是写了一些干货的。 本文直接参考 Doug Lea 写的 Java doc 和注释,这也是我们在学习 java 并发包时最好的材料了。希望大家能有所思、有所悟,学习 Doug Lea 的代码风格,并将其优雅、严谨的作风应用到我们写的每一行代码中。 目录: BlockingQueue 开篇先介绍下 BlockingQueue 这个接口的规则,后面再看其实现。 首先,最基本的来说, BlockingQueue 是一个先进先出的队列(Queue),为什么说是阻塞(Blocking)的呢?是因为

Collection

夙愿已清 提交于 2020-07-26 15:58:05
Collection继承关系图 Collection类 Set、List、Map、Queue使用场景梳理 1 方法摘要 2 boolean add(E e) 3 确保此 collection 包含指定的元素(可选操作)。 4 boolean addAll(Collection<? extends E> c) 5 将指定 collection 中的所有元素都添加到此 collection 中(可选操作)。 6 void clear() 7 移除此 collection 中的所有元素(可选操作)。 8 boolean contains(Object o) 9 如果此 collection 包含指定的元素,则返回 true 。 10 boolean containsAll(Collection<?> c) 11 如果此 collection 包含指定 collection 中的所有元素,则返回 true 。 12 boolean equals(Object o) 13 比较此 collection 与指定对象是否相等。 14 int hashCode() 15 返回此 collection 的哈希码值。 16 boolean isEmpty() 17 如果此 collection 不包含元素,则返回 true 。 18 Iterator<E> iterator() 19 返回在此

带你认识不一样的Stream,Java8就该这么玩!

浪子不回头ぞ 提交于 2020-07-24 06:36:28
云栖号资讯:【 点击查看更多行业资讯 】 在这里您可以找到不同行业的第一手的上云资讯,还在等什么,快来! 相信Java8的Stream 大家都已听说过了,但是可能大家不会用或者用的不熟,文章将带大家从零开始使用,循序渐进,带你走向Stream的巅峰。 操作符 什么是操作符呢?操作符就是对数据进行的一种处理工作,一道加工程序;就好像工厂的工人对流水线上的产品进行一道加工程序一样。 Stream的操作符大体上分为两种:中间操作符和终止操作符 中间操作符 对于数据流来说,中间操作符在执行制定处理程序后,数据流依然可以传递给下一级的操作符。 中间操作符包含8种(排除了parallel,sequential,这两个操作并不涉及到对数据流的加工操作): map(mapToInt,mapToLong,mapToDouble) 转换操作符,把比如A->B,这里默认提供了转int,long,double的操作符。 flatmap(flatmapToInt,flatmapToLong,flatmapToDouble) 拍平操作比如把 int[]{2,3,4} 拍平 变成 2,3,4 也就是从原来的一个数据变成了3个数据,这里默认提供了拍平成int,long,double的操作符。 limit 限流操作,比如数据流中有10个 我只要出前3个就可以使用。 distint 去重操作,对重复元素去重

Java8 Stream新特性详解及实战

烂漫一生 提交于 2020-05-08 10:20:37
Java8 Stream新特性详解及实战 背景介绍 在阅读Spring Boot源代码时,发现Java 8的新特性已经被广泛使用,如果再不学习Java8的新特性并灵活应用,你可能真的要out了。为此,针对Java8的新特性,会更新一系列的文章,欢迎大家持续关注。 首先,我们来看一下Spring Boot源代码ConfigFileApplicationListener类中的一段代码: private List<Profile> getOtherActiveProfiles(Set<Profile> activatedViaProperty) { return Arrays.stream(this.environment.getActiveProfiles()).map(Profile::new) .filter((profile) -> !activatedViaProperty.contains(profile)) .collect(Collectors.toList()); } 这段代码怎么?够简洁明快吧,如果不使用Java8的新特性,想象一下得多少行代码才能实现?但如果没掌握或不了解Java8的新特性,这段代码读起来是不是很酸爽? Java 8的API中新增了一个处理集合的抽象概念:Stream,中文称作“流”。它可以指定你希望对集合进行的操作,可以执行非常复杂的查找

[Java]算术表达式求值之二(中序表达式转后序表达式方案,支持小数)

烈酒焚心 提交于 2020-05-08 09:30:16
Inlet类,入口类,这个类的主要用途是验证用户输入的算术表达式: package com.hy; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; // 此类用于把算术表达式送入解析器 public class Inlet { public static void main(String[] args) throws IOException{ // 取得用户输入的表达式 BufferedReader br = new BufferedReader( new InputStreamReader(System.in)); String rawExpression = null ; System.out.print( "请输入算术表达式:" ); rawExpression = br.readLine(); // 得到合法的算术表达式 String expression="" ; for ( int i=0;i<rawExpression.length();i++ ){ // 拿到表达式的每个字符 char c= rawExpression.charAt(i); // System.out.print(c+","); if (Character