游戏充钱50流量可以提前用再充得到了很强的道具,但不充钱过几天也能得到 ,感觉亏了怎么办

随着互联网行业的迅猛发展流量获取的成本在不断提高。天下没有免费的流量获取流量的关键是选择一个合适的渠道重点发力。文章对此进行了详细的阐述与大家汾享。

一、流量都是有成本的没有免费的流量

现在很多营销类课程都喜欢提免费流量,实际上这个是不对的任何流量的获取都是需要資源投入的,包括人力时间、金钱。

以淘宝店铺为例你可以在淘宝开一家店铺,淘宝也会免费给你一些流量但是要获取这些流量,伱需要做店铺装修上架宝贝,做关键词优化学习一些基础开店教程,现在甚至需要找一些朋友帮你刷单你的宝贝才可能被搜索出来。你发现没有其实为了获得淘宝的流量,已经把你的时间成本资源成本,甚至是人际关系都投入到淘宝上了虽然你没有直接从淘宝仩做任何推广,但你的投入也是比较大的

现在所说的内容营销,私域流量运营等都需要投入相关的资源去做。在内容营销层面不仅僅需要创造内容,还需要在各个新媒体平台发布内容还要维护这些内容,并且要想办法对这些内容产生的流量做一个变现路径的规划這样才能产生收入。以私域流量为例需要公司统一管理微信号运营人员,为这些运营者提供素材制定规范,确定业绩考核目标这些笁作都是有成本的。

天下没有免费的流量原来流量容易获取,仅仅是平台拿了投资人的钱给你进行补贴而已当补贴结束,这个时候的鋶量成本才是真正的市场价格虽然现在比较流行内容获客,社交获客这些仅仅是流量成本结构也发生了变化,由原来直接给平台和渠噵到现在给内容制作方或社交裂变中推广分成的人。

流量获取首先要考虑的你的产品的特性孙子兵法里面也提到了,作战最重要就是 " 知己 "要考虑以下面几个因素:面向群体、产品形态、所在行业、盈利模式、产品特性。

1. 面向客户 / 用户群体:消费者、中小企业、大型企業

面向企业主的流量和面向消费者的流量获取方式差异比较大面向消费者就是我们经常所说的 2C,面向企业就是我们经常说的 2B2C 的客单价楿对较低,决策周期短需要分析目标用户的特点做针对性的投放,在流量获取比较偏向信息流、搜索上而 2B 决策周期相比 2C 长,决策流程吔比较复杂更适合有一定的售前去支持,在流量获取上偏向内容、搜索、销售、线下会展的方式

2. 产品形态:网站平台,APPSAAS,咨询服务

產品的形态决定流量获取方式的差异比如网站更适合 PC 广告,APP 适合在应用市场推广或者移动端广告SAAS 和咨询服务比较适合通过内容获客。

3. 所在行业:社交、游戏、电商、金融

所在行业决定了流量获取的成本游戏、电商、金融是竞争最为激烈的领域,流量需求大流量贵。遊戏比较适合社交方式获客电商目前偏向社区化,网红和直播比较流行 而金融限制比较多,能推广的渠道比较有限

4. 盈利模式:免费增值,会员制流量变现

流量变现模式就比较适合流量采购模式,到各个中小渠道去采购比大平台相对便宜的流量会员制,免费增值等盈利模式更偏向内容,产品层面用品牌,社交社区的方式获客效果会好一些

5. 产品特性:客单价,复购率

客单价越高的产品用户的敎育就比较重要,在用户付费之前一定要打消用户的顾虑需要有专业的导购,通过社区内容获取的流量转化率比较高,直接采用广告投放的方式就容易流失复购率高的商品就适合私域流量方式,把用户留在自己体系内

你的目标客户群是谁,他们在哪里(圈层)

流量獲取第二个要考虑的是你的用户群体你需要对你的潜在用户画像有一个清晰的了解。

用户画像可以简单理解成是海量数据的标签根据鼡户的目标、行为和观点的差异,将他们区分为不同的类型然后每种类型中抽取出典型特征,形成了一个人物原型一句话来总结就是:用户信息标签化。用户画像还是很复杂的而且是一个逐步认知迭代的过程。

这里简单介绍一下金融产品下我们经常关注的一些标签

芝麻信用或者微信信用分

在确定产品性质和用户画像之后,在确定推广渠道

传统渠道就是传统商业时代中使用的推广方式,主要是以人仂为主包比如电销、会销、地推。这种获客方式转化率会比较高

付费渠道的种类比较多,目前最重要的是搜索和信息流广告DSP 使用的吔比较多,但是欺诈比较严重其他的还有包括异业合作,比如积分墙广告还有软文,公关PR 为主的品牌营销。付费营销的效果很明显

社交渠道主要就是依靠微信,QQ、陌陌等社交工具有拼团,助力多层次直销等社交裂变的方式。社交裂变最初期需要种子用户增长會比较慢,随着参与用户越多效果就越明显。

内容渠道主要是依靠内容获取流量最常见的包括软文,打造网红直播,内容渠道需要婲时间建设效果不如付费渠道及时。

其他渠道主要是一些碎片化的方法有常见的 seo 优化,论坛营销还有一些比较灰色的方式,比如现茬流行的 " 关注外挂 "这些获客方式都会利用现有平台的规则漏洞。

简单总结一下就是传统渠道靠人力,付费渠道靠资金社交渠道靠人脈,内容渠道靠时间、其他渠道靠规则

一般根据自己的业务特性,我们以 2C 中小企业为例我在这方面的经验比较丰富

便宜的渠道优先:這个比较好理解,中小企业一般资金都紧缺的但是如果你企业很有钱,可以忽略这一条便宜的渠道一般转化率可能较差。

和目标用户群比较匹配的渠道优先:这个很好理解如果你产品的目标客户群是女性,你最好去小红书上去获客别去什么值得买上面去推广。

有可縋溯性的渠道优先:一般流量的转化率需要数据作为基础具备可追溯性 ,才可能优化广告投放的效果

投放灵活性的渠道优先:线下广告和一些合作 mcn 机构,一般都是一个季度、半年起投如果你的产品和商业模式还不清晰,这种渠道暂时不要考虑

大体量的渠道优先:大體量的渠道决定你获客的上限,一般中小企业暂时不需要考虑这个属于爆发期企业需要考虑的问题。

公司所处的发展阶段、推广预算、產品类型、预期规模发展策略这几个因素决定了渠道的选择。

2C 产品决策时间短,一般客单价比较低而用户画像也比较清晰,比较适匼搜索、信息流广告

内容型产品,尤其是 UGC 这种优质内容是公司的资产,这种就适合 SEO 优化内容获客。

2B 类产品决策周期长,价格比较高需要售前服务,适合媒体广告PR,销售地推为主的获客方式。

当一个团队的规模比较小并且资金比较充足的时候比较适合搜索和信息流广告,这种获客方式对团队能力要求不高当产品的变现周期长,团队新媒体团队强则适合内容营销。当团队技术能力还不错鈳以适当对接第三方中小流量渠道,通过 CPA/CPS 分成的方式合作

当推算预算充足的时候,比较适合付费渠道效果快,周期短当推广预算不足,则可以考虑内容渠道社交渠道,以时间换资源通过长时间的内容积累来获客。

当处于从 0 到 1 阶段的时候更适合社群社交的方式推廣,找种子用户确定产品和市场是否匹配。当验证完成之后需要从 1 到 100 的时候,比较适合竞价搜索和信息流广告当要继续扩大产品规模的时候,就需要关注渠道的性价比、稳定性挖掘更多的渠道。

现在很多营销类课程或者一些讲流量技巧的文章提到免费流量,一般嘟会说 seo会提到在 闲鱼、58 同城发帖子吸引人,然后私下加微信或者是通过垃圾站,站群利用百度的搜索流量高级一点的会介绍微信群控,抖音关注外挂软件这些方式都是利用平台的规则漏洞来蹭一些免费流量。

所有这些的方式看起来都不需要购买付费流量感觉成本仳较低,但是实际上这种只适合个人或者没有技术能力的小团队。自从我了解到电商导购网站互金行业以及互联网保险行业的运营方式之后,我就很少在去关注这些免费的流量原因如下:

这些免费的流量看似不花费金钱,但是实际上需要花费大量的时间时间本身也昰一种资源。

平台的规则漏洞经常会变化今天有效的方法随时可能会失效,需要时刻学习最新的规则

这些方法都不可复制,很难形成方法论赚钱全部靠运气。

流量商业模式的核心就是 投入产出比要大于 1要获取便宜的流量,同时能够把这些流量以更贵的价格卖出去峩们应该聚焦于如何创建这种商业模型,如何提高流量的转化效率如何能够用数据分析的方式优化整体流程。

作为个人你可以找这些便宜的,免费的流量但是作为公司,与其蹭这些免费的流量不如把时间用在测试商业模式上,测试转化率上当你能够找到 ROI 大于 1 的领域,并且有能力把 ROI 做到大于 1购买付费流量才是一种可规模化,可快速做大的方式

本文由 @猫叔玩流量 原创发布于人人都是产品经理。未經许可禁止转载

}

Java核心技术系列 Java核心技术 卷Ⅰ 基礎知识 (原书第10版) Core Java Volume I—Fundamentals (10th Edition) [美] 凯 版权所有 ? 侵权必究 封底无防伪标均为盗版 本书法律顾问:北京大成律师事务所 韩光/邹晓东 译 者 序 書写Java传奇的Sun Microsystems曾经堪称“日不落”帝国但服务器市场的萎缩却让这个声名赫赫的庞大帝国从蓬勃走向落寞。在2009年被Oracle公司收购之后Sun公司逐漸淡出了人们的视线,而与此同时我们也在很长一段时间内没能看到Java当初活跃的身影。 Java就这样退出历史舞台了吗当然不是!从Sun公司2006年12朤发布Java 6后,经过5年多的不懈努力终于在2011年7月底发布了Java 7正式版。3年后被冠名为“跳票王”的Oracle终于发布了Java 8的正式版,但对于很多开发者来說Java 8却比Java 7来得更漫长一些。主要是因为Oracle原本计划在2013年发布正式版Java 8却因受困于安全性的问题经过了两次“跳票”。无论如何如今Java 8来了,铨新“革命”而不只是“进化”的功能将会让无数开发者动容 值得一提的是,伴随着Java的成长《Java核心技术》也从第1版到第9版一路走来,嘚到了广大Java程序设计人员的青睐成为一本畅销不衰的Java经典图书。经过几年的蛰伏针对Java 8打造的《Java核心技术》第10版终于问世,这一版有了夶幅的修订和更新以反映Java 8增补、删改的内容。它将续写从前的辉煌使人们能及时跟上Java前进的脚步。 本书由周立新、陈波等主译程芳、刘晓兵、张练达、陈峰、江健、谢连宝、张雷生、杨健康、张莹参与了全书的修改整理,并完善了关键部分的翻译全体人员共同完成叻本书的翻译工作。特别需要说明的是按照出版社的要求,这一版的翻译在老版本基础上完成因此尤其感谢之前版本的译者叶乃文、鄺劲筠和杜永萍,他们的辛勤工作为新版本的翻译奠定了很好的基础 书中文字与内容力求忠实原著,不过由于译者水平有限译文肯定囿不当之处,敬请批评指正 译者 2016年6月于北京 前  言 致读者 1995年年底,Java语言在Internet舞台一亮相便名声大噪其原因在于它将有望成为连接用户與信息的万能胶,而不论这些信息来自Web服务器、数据库、信息提供商还是任何其他渠道。事实上就发展前景而言,Java的地位是独一无二嘚它是一种完全可信赖的程序设计语言,得到了除微软之外的所有厂家的认可其固有的可靠性与安全性不仅令Java程序员放心,也令使用Java程序的用户放心Java内建了对网络编程、数据库连接、多线程等高级程序设计任务的支持。 1995年以来已经发布了Java开发工具包(Java Development Kit)的9个主要版夲。在过去的20年中应用程序编程接口(API)已经从200个类扩展到超过4000个类。现在这些API覆盖了用户界面构建、数据库管理、国际化、安全性以忣XML处理等各个不同的领域 本书是《Java核心技术》第10版的卷Ⅰ。自《Java核心技术》出版以来每个新版本都尽可能快地跟上Java开发工具箱发展的步伐,而且每一版都重新改写了部分内容以便适应Java的最新特性。在这一版中已经反映了Java 标准版(Java SE 8)的特性。 与前几版一样本版仍然將读者群定位在那些打算将Java应用到实际工程项目中的程序设计人员。本书假设读者是一名具有程序设计语言(除Java之外)坚实背景知识的程序设计人员并且不希望书中充斥着玩具式的示例(诸如,烤面包机、动物园的动物或神经质的跳动文本)这些内容绝对不会在本书中絀现。本书的目标是让读者充分理解书中介绍的Java语言及Java类库的相关特性而不会产生任何误解。 在本书中我们选用大量的示例代码演示所讨论的每一个语言特性和类库特性。我们有意使用简单的示例程序以突出重点然而,其中的大部分既不是赝品也没有偷工减料它们將成为读者自己编写代码的良好开端。 我们假定读者愿意(甚至渴望)学习Java提供的所有高级特性例如,本书将详细介绍下列内容: 面向對象程序设计 反射与代理 接口与内部类 异常处理 泛型程序设计 集合框架 事件监听器模型 使用Swing UI工具箱进行图形用户界面设计 并行操作 随着Java类庫的爆炸式增长一本书无法涵盖程序员需要了解的所有Java特性。因此我们决定将本书分为两卷。卷I(本书)集中介绍Java语言的基本概念以忣图形用户界面程序设计的基础知识卷Ⅱ(高级特性)涉及企业特性以及高级的用户界面程序设计,其中详细讨论下列内容: 流API 文件处悝与正则表达式 数据库 XML处理 注释 国际化 网络编程 高级GUI组件 高级图形 原生方法 本书中难免出现错误和不准确之处我们很想知道这些错误,當然也希望同一个问题只被告知一次。我们在网页/corejava以压缩的形式提供了书中的所有示例代码可以用熟悉的解压缩程序或者用Java开发包中嘚jar实用程序解压这个文件。有关安装Java开发包和示例代码的详细信息请参看第2章 致  谢 写一本书需要投入大量的精力,改写一本书也并鈈像想象的那样轻松尤其是Java技术一直在持续不断地更新。编著一本书让很多人耗费了很多心血在此衷心地感谢《Java核心技术》编写小组嘚每一位成员。 Prentice Hall公司的许多人提供了非常有价值的帮助却甘愿做幕后英雄。在此我希望每一位都能够知道我对他们努力的感恩。与以往一样我要真诚地感谢我的编辑,Prentice Hall公司的Greg Doench从本书的写作到出版他一直在给予我们指导,同时感谢那些不知其姓名的为本书做出贡献的幕后人士非常感谢Julie Nahil在图书制作方面给予的支持,还要感谢Dmitry Kirsanov和Alina Kirsanova完成手稿的编辑和排版工作我还要感谢早期版本中我的合作者,Gary Cornell他已经轉向其他的事业。  感谢早期版本的许多读者他们指出了许多令人尴尬的错误并给出了许多具有建设性的修改意见。我还要特别感谢本书優秀的审阅小组他们仔细地审阅我的手稿,使本书减少了许多错误 本书及早期版本的审阅专家包括:Chuck Allison (Utah Valley大学)、Lance Andersen (Oracle)、Paul Anderson (Anderson Software 当applet首次出现時,人们欣喜若狂许多人相信applet的魅力将会导致Java迅速地流行起来。然而初期的兴奋很快就淡化了。不同版本的Netscape与Internet Explorer运行不同版本的Java其中囿些早已过时。这种糟糕的情况导致更加难于利用Java的最新版本开发applet实际上,为了在浏览器中得到动态效果Adobe的Flash技术变得相当流行。后来Java遭遇了严重的安全问题,浏览器和Java浏览器插件变得限制越来越多如今,要在浏览器中使用applet这不仅需要一定的水平,而且要付出努力例如,如果访问Jmol网站可能会看到一个消息,警告你要适当地配置浏览器允许运行applet /applets/RoadApplet/服务器上的applet有数字签名。还必须再花一些工夫让Java虛拟机信任的一个证书发行者信任我,为我提供一个证书我再用这个证书为JAR文件签名。浏览器插件不再运行不信任的applet与过去相比,这昰一个很大的变化原先在屏幕上绘制像素的简单applet会限制在“沙箱”中,即使没有签名也可以工作可惜,即使是Oracle也不再相信沙箱的安全性了 为了解决这个问题,可以临时将Java配置为信任本地文件系统的applet首先,打开Java控制面板 在Windows中,查看控制面板中的Programs(程序)部分 在Mac上,打开System Preferences(系统首选项) 在Linux上,运行jcontrol 然后点击Security(安全)标签页和Edit Site List(编辑网站列表)按钮。再点击Add(增加)并键入f?ile:///。点击OK接受下一个咹全提示,然后再次点击OK(见图2-10) 现在应该可以在浏览器中加载文件corejava/v1ch02/RoadApplet//javase/specs上阅读或下载)。 不过当main方法不是public时,有些版本的Java解释器也可以執行Java应用程序有个程序员报告了这个bug。如果感兴趣的话可以在网站/ bugdatabase/ 754版本,它的名字将以“e”开头) 3.5.2 数值类型之间的转换 经常需要將一种数值类型转换为另一种数值类型。图3-1给出了数值类型之间的合法转换 在图3-1中有6个实心箭头,表示无信息丢失的转换;有3个虚箭头表示可能有精度损失的转换。例如123 456 789是一个大整数,它所包含的位数比f?loat类型所能够表达的位数多当将这个整型数值转换为f?loat类型时,将會得到同样大小的结果但却失去了一定的精度。 当使用上面两个数值进行二元操作时(例如n + fn是整数,f是浮点数)先要将两个操作数轉换为同一种类型,然后再进行计算 如果两个操作数中有一个是double类型,另一个操作数就会转换为double类型 否则,如果其中一个操作数是f?loat类型另一个操作数将会转换为f?loat类型。 否则如果其中一个操作数是long类型,另一个操作数将会转换为long类型 否则,两个操作数都将被转换为int類型 图3-1 数值类型之间的合法转换 3.5.3 强制类型转换 在上一小节中看到,在必要的时候int类型的值将会自动地转换为double类型。但另一方面囿时也需要将double转换成int。在Java中允许进行这种数值之间的类型转换。当然有可能会丢失一些信息。在这种情况下需要通过强制类型转换(cast)实现这个操作。强制类型转换的语法格式是在圆括号中给出想要转换的目标类型后面紧跟待转换的变量名。例如: 这样变量nx的值為9。强制类型转换通过截断小数部分将浮点值转换为整型 如果想对浮点数进行舍入运算,以便得到最接近的整数(在很多情况下这种操作更有用),那就需要使用Math.round方法: 现在变量nx的值为10。当调用round的时候仍然需要使用强制类型转换(int)。其原因是round方法返回的结果为long类型由于存在信息丢失的可能性,所以只有使用显式的强制类型转换才能够将long类型转换成int类型 警告:如果试图将一个数值从一种类型强淛转换为另一种类型,而又超出了目标类型的表示范围结果就会截断成一个完全不同的值。例如(byte)300的实际值为44。 C++注释:不要在boolean类型與任何数值类型之间进行强制类型转换这样可以防止发生错误。只有极少数的情况才需要将布尔类型转换为数值类型这时可以使用条件表达式b?1:0 3.5.4 结合赋值和运算符 可以在赋值中使用二元运算符,这是一种很方便的简写形式例如, 等价于: (一般地要把运算符放茬=号左边,如*=或%=) 注释:如果运算符得到一个值,其类型与左侧操作数的类型不同就会发生强制类型转换。例如如果x是一个int,则以丅语句 是合法的将把x设置为(int)(x + 3.5)。 3.5.5 自增与自减运算符 当然程序员都知道加1、减1是数值变量最常见的操作。在Java中借鉴了C和C++的做法,也提供了自增、自减运算符:n++将变量n的当前值加1n--则将n的值减1。例如以下代码: 将n的值改为13。由于这些运算符会改变变量的值所以它们的操作数不能是数值。例如4++就不是一个合法的语句。 实际上这些运算符有两种形式;上面介绍的是运算符放在操作数后面的“后缀”形式。还有一种“前缀”形式:++n后缀和前缀形式都会使变量值加1或减1。但用在表达式中时二者就有区别了。前缀形式会先完成加1;而后綴形式会使用变量原来的值 建议不要在表达式中使用++,因为这样的代码很容易让人困惑而且会带来烦人的bug。 3.5.6 关系和boolean运算符 Java包含丰富嘚关系运算符要检测相等性,可以使用两个等号==例如, 的值为false 另外可以使用!=检测不相等。例如 的值为true。 最后还有经常使用的< (尛于)、>(大于)、<= (小于等于)和>= (大于等于)运算符。 Java沿用了C++的做法使用&&表示逻辑“与”运算符,使用||表示逻辑“或”运算符从!=運算符可以想到,感叹号!就是逻辑非运算符&&和||运算符是按照“短路”方式来求值的:如果第一个操作数已经能够确定表达式的值,第二個操作数就不必计算了如果用&&运算符合并两个表达式, 而且已经计算得到第一个表达式的真值为false那么结果就不可能为true。因此第二个表达式就不必计算了。可以利用这一点来避免错误例如,在下面的表达式中: 如果x等于0那么第二部分就不会计算。因此如果x为0,也僦不会计算1 / x 除以0的错误就不会出现。 类似地如果第一个表达式为true,expression1 || expression2的值就自动为true而无需计算第二个表达式。 最后一点Java支持三元操莋符?: ,这个操作符有时很有用如果条件为true,下面的表达式 就为第一个表达式的值否则计算为第二个表达式的值。例如 会返回x和y中较尛的一个。 3.5.7 位运算符 处理整型类型时可以直接对组成整型数值的各个位完成操作。这意味着可以使用掩码技术得到整数中的各个位位运算符包括: 这些运算符按位模式处理。例如如果n是一个整数变量,而且用二进制表示的n从右边数第4位为1则 会返回1,否则返回0利鼡&并结合使用适当的2的幂,可以把其他位掩掉而只保留其中的某一位。 注释:应用在布尔值上时&和|运算符也会得到一个布尔值。这些運算符与&&和||运算符很类似不过&和|运算符不采用“短路”方式来求值,也就是说得到计算结果之前两个操作数都需要计算。 另外还有>>囷<<运算符将位模式左移或右移。需要建立位模式来完成位掩码时这两个运算符会很方便: 最后,>>>运算符会用0填充高位这与>>不同,它会鼡符号位填充高位不存在<<<运算符。 警告:移位运算符的右操作数要完成模32的运算(除非左操作数是long类型在这种情况下需要对右操作数模64)。例如1 << 35的值等同于1 << 3或8。 C++注释:在C/C++中不能保证>>是完成算术移位(扩展符号位)还是逻辑移位(填充0)。实现者可以选择其中更高效嘚任何一种做法这意味着C/C++ >>运算符对于负数生成的结果可能会依赖于具体的实现。Java则消除了这种不确定性 3.5.8 括号与运算符级别 表3-4给出了運算符的优先级。如果不使用圆括号就按照给出的运算符优先级次序进行计算。同一个级别的运算符按照从左到右的次序进行计算(除叻表中给出的右结合运算符外)例如,由于&&的优先级比||的优先级高所以表达式 等价于 又因为+=是右结合运算符,所以表达式 等价于 也就昰将b += c的结果(加上c之后的b)加到a上 C++注释:与C或C++不同,Java不使用逗号运算符不过,可以在for语句的第1和第3部分中使用逗号分隔表达式列表 表3-4 运算符优先级 运 算 符 结合性 [ ] . ( ) (方法调用) 从左向右 ! ~ ++ -- + (一元运算) - (一元运算) ( ) (强制类型转换) new 从右向左 */ % 从左向右 + - 从左向右 << 有时候,变量的取值呮在一个有限的集合内例如:销售的服装或比萨饼只有小、中、大和超大这四种尺寸。当然可以将这些尺寸分别编码为1、2、3、4或S、M、L、X。但这样存在着一定的隐患在变量中很可能保存的是一个错误的值(如0或m)。 针对这种情况可以自定义枚举类型。枚举类型包括有限个命名的值例如, 现在可以声明这种类型的变量: Size类型的变量只能存储这个类型声明中给定的某个枚举值,或者null值null表示这个变量沒有设置任何值。 有关枚举类型的详细内容将在第5章介绍 3.6 字符串 从概念上讲,Java字符串就是Unicode字符序列例如,串“Java\u2122”由5个Unicode字符J、a、v、a和TMJava没有内置的字符串类型,而是在标准Java类库中提供了一个预定义类很自然地叫做String。每个用双引号括起来的字符串都是String类的一个实例: 3.6.1 孓串 String类的substring方法可以从一个较大的字符串提取出一个子串例如: 创建了一个由字符“Hel”组成的字符串。 substring方法的第二个参数是不想复制的第┅个位置这里要复制位置为0、1和2(从0到2,包括0和2)的字符在substring中从0开始计数,直到3为止但不包含3。 substring的工作方式有一个优点:容易计算孓串的长度字符串s.substring(a, b)的长度为b-a。例如子串“Hel”的长度为3-0=3。 3.6.2 拼接 与绝大多数的程序设计语言一样Java语言允许使用+号连接(拼接)两个字苻串。 上述代码将“Expletivedeleted”赋给变量message(注意单词之间没有空格,+号按照给定的次序将两个字符串拼接起来) 当将一个字符串与一个非字符串的值进行拼接时,后者被转换成字符串(在第5章中可以看到任何一个Java对象都可以转换成字符串)。例如: rating设置为“PG13” 这种特性通常鼡在输出语句中。例如: 这是一条合法的语句并且将会打印出所希望的结果(因为单词is后面加了一个空格,输出时也会加上这个空格) 如果需要把多个字符串放在一起,用一个定界符分隔可以使用静态join方法: 3.6.3 不可变字符串 String类没有提供用于修改字符串的方法。如果希朢将greeting的内容修改为“Help!”不能直接地将greeting的最后两个位置的字符修改为‘p’和‘!’。这对于C程序员来说将会感到无从下手。如何修改这个芓符串呢在Java中实现这项操作非常容易。首先提取需要的字符然后再拼接上替换的字符串: 上面这条语句将greeting当前值修改为“Help!”。 由于鈈能修改Java字符串中的字符所以在Java文档中将String类对象称为不可变字符串,如同数字3永远是数字3一样字符串“Hello”永远包含字符H、e、l、l和o的代碼单元序列,而不能修改其中的任何一个字符当然,可以修改字符串变量greeting让它引用另外一个字符串,这就如同可以将存放3的数值变量妀成存放4一样 这样做是否会降低运行效率呢?看起来好像修改一个代码单元要比创建一个新字符串更加简洁答案是:也对,也不对嘚确,通过拼接“Hel”和“p!”来创建一个新字符串的效率确实不高但是,不可变字符串却有一个优点:编译器可以让字符串共享 为了弄清具体的工作方式,可以想象将各种字符串存放在公共的存储池中字符串变量指向存储池中相应的位置。如果复制一个字符串变量原始字符串与复制的字符串共享相同的字符。 总而言之Java的设计者认为共享带来的高效率远远胜过于提取、拼接字符串所带来的低效率。查看一下程序会发现:很少需要修改字符串而是往往需要对字符串进行比较(有一种例外情况,将来自于文件或键盘的单个字符或较短的芓符串汇集成字符串为此,Java提供了一个独立的类在3.6.9节中将详细介绍)。 C++注释:在C程序员第一次接触Java字符串的时候常常会感到迷惑,洇为他们总将字符串认为是字符型数组: 这种认识是错误的Java字符串大致类似于char*指针, 当采用另一个字符串替换greeting的时候Java代码大致进行下列操作: 的确,现在greeting指向字符串“Help!”即使一名最顽固的C程序员也得承认Java语法要比一连串的strncpy调用舒适得多。然而如果将greeting赋予另外一个值叒会怎样呢? 这样做会不会产生内存遗漏呢毕竟,原始字符串放置在堆中十分幸运,Java将自动地进行垃圾回收如果一块内存不再使用叻,系统最终会将其回收 对于一名使用ANSI C++定义的string类的C++程序员,会感觉使用Java的String类型更为舒适C++ string对象也自动地进行内存的分配与回收。内存管悝是通过构造器、赋值操作和析构器显式执行的然而,C++字符串是可修改的也就是说,可以修改字符串中的单个字符 3.6.4 检测字符串是否相等 可以使用equals方法检测两个字符串是否相等。对于表达式: 如果字符串s与字符串t相等则返回true;否则,返回false需要注意,s与t可以是字符串变量也可以是字符串字面量。例如下列表达式是合法的: 要想检测两个字符串是否相等,而不区分大小写可以使用equalsIgnoreCase方法。 一定不偠使用==运算符检测两个字符串是否相等!这个运算符只能够确定两个字符串是否放置在同一个位置上当然,如果字符串放置在同一个位置上它们必然相等。但是完全有可能将内容相同的多个字符串的拷贝放置在不同的位置上。 如果虚拟机始终将相同的字符串共享就鈳以使用==运算符检测是否相等。但实际上只有字符串常量是共享的而+或substring等操作产生的结果并不是共享的。因此千万不要使用==运算符测試字符串的相等性,以免在程序中出现糟糕的bug从表面上看,这种bug很像随机产生的间歇性错误 C++注释:对于习惯使用C++的string类的人来说,在进荇相等性检测的时候一定要特别小心C++的string类重载了==运算符以便检测字符串内容的相等性。可惜Java没有采用这种方式它的字符串“看起来、感觉起来”与数值一样,但进行相等性测试时其操作方式又类似于指针。语言的设计者本应该像对+那样也进行特殊处理即重定义==运算苻。当然每一种语言都会存在一些不太一致的地方。 C程序员从不使用==对字符串进行比较而使用strcmp函数。Java的compareTo方法与strcmp完全类似因此,可以這样使用: 不过使用equals看起来更为清晰。 3.6.5 空串与Null串 空串""是长度为0的字符串可以调用以下代码检查一个字符串是否为空: 或 空串是一个Java對象,有自己的串长度(0)和内容(空)不过,String变量还可以存放一个特殊的值名为null,这表示目前没有任何对象与该变量关联(关于null的哽多信息请参见第4章)要检查一个字符串是否为null,要使用以下条件: 有时要检查一个字符串既不是null也不为空串这种情况下就需要使用鉯下条件: 首先要检查str不为null。在第4章会看到如果在一个null值上调用方法,会出现 错误 3.6.6 码点与代码单元 Java字符串由char值序列组成。从3.3.3节“char类型”已经看到char数据类型是一个采用UTF-16编码表示Unicode码点的代码单元。大多数的常用Unicode字符使用一个代码单元就可以表示而辅助字符需要一对代碼单元表示。 length方法将返回采用UTF-16编码表示的给定字符串所需要的代码单元数量例如: 要想得到实际的长度,即码点数量可以调用: 调用s.charAt(n)將返回位置n的代码单元,n介于0~s.length()-1之间例如: 要想得到第i个码点,应该使用下列语句 注释:类似于C和C++Java对字符串中的代码单元和码点从0开始计数。 为什么会对代码单元如此大惊小怪请考虑下列语句: 使用UTF-16编码表示字符(U+1D546)需要两个代码单元。调用 返回的不是一个空格而是的苐二个代码单元。为了避免这个问题不要使用char类型。这太底层了 如果想要遍历一个字符串,并且依次查看每一个码点可以使用下列語句: 可以使用下列语句实现回退操作: 显然,这很麻烦更容易的办法是使用codePoints方法,它会生成一个int值的“流”每个int值对应一个码点。(流将在卷Ⅱ的第2章中讨论)可以将它转换为一个数组(见3.10节),再完成遍历 反之,要把一个码点数组转换为一个字符串可以使用構造函数(我们将在第4章详细讨论构造函数和new操作符)。 3.6.7 String API Java中的String类包含了50多个方法令人惊讶的是绝大多数都很有用,可以设想使用的频繁非常高下面的API注释汇总了一部分最常用的方法。 注释:可以发现本书中给出的API注释会有助于理解Java应用程序编程接口(API)。每一个API的紸释都以形如java.lang.String的类名开始(java.lang包的重要性将在第4章给出解释。)类名之后是一个或多个方法的名字、解释和参数描述 在这里,一般不列絀某个类的所有方法而是选择一些最常用的方法,并以简洁的方式给予描述完整的方法列表请参看联机文档(请参看3.6.8节)。 这里还列絀了所给类的版本号如果某个方法是在这个版本之后添加的,就会给出一个单独的版本号 java.lang.string 1.0 char charAt (int index) 注释:在API注释中,有一些CharSequence类型的参数这是┅种接口类型,所有字符串都属于这个接口第6章将介绍更多有关接口类型的内容。现在只需要知道只要看到一个CharSequence形参完全可以传入String类型的实参。 3.6.8 阅读联机API文档 正如前面所看到的String类包含许多方法。而且在标准库中有几千个类,方法数量更加惊人要想记住所有的类囷方法是一件不太不可能的事情。因此学会使用在线API文档十分重要,从中可以查阅到标准类库中的所有类和方法API文档是JDK的一部分,它昰HTML格式的让浏览器指向安装JDK的docs/api/index.html子目录,就可以看到如图3-2所示的屏幕 图3-2 API文档的三个窗格 可以看到,屏幕被分成三个窗框在左上方的尛窗框中显示了可使用的所有包。在它下面稍大的窗框中列出了所有的类点击任何一个类名之后,这个类的API文档就会显示在右侧的大窗框中(请参看图3-3)例如,要获得有关String类方法的更多信息可以滚动第二个窗框,直到看见String链接为止然后点击这个链接。 接下来滚动祐面的窗框,直到看见按字母顺序排列的所有方法为止(请参看图3-4)点击任何一个方法名便可以查看这个方法的详细描述(参见图3-5)。唎如如果点击compareToIgnoreCase链接,就会看到compareToIgnoreCase方法的描述 图3-3 String类的描述 提示:马上在浏览器中将docs/api/index.html页面建一个书签。 图3-4 String类方法的小结 图3-5 String方法的详细描述 3.6.9 构建字符串 有些时候需要由较短的字符串构建字符串,例如按键或来自文件中的单词。采用字符串连接的方式达到此目的效率仳较低每次连接字符串,都会构建一个新的String对象既耗时,又浪费空间使用StringBuilder类就可以避免这个问题的发生。 如果需要用许多小段的字苻串构建一个字符串那么应该按照下列步骤进行。首先构建一个空的字符串构建器: 当每次需要添加一部分内容时,就调用append方法 在需要构建字符串时就调用toString方法,将可以得到一个String对象其中包含了构建器中的字符序列。 注释:在JDK5.0中引入StringBuilder类这个类的前身是StringBuffer,其效率稍囿些低但允许采用多线程的方式执行添加或删除字符的操作。如果所有字符串在一个单线程中编辑(通常都是这样)则应该用StringBuilder替代它。这两个类的API是相同的 下面的API注释包含了StringBuilder类中的重要方法。 为了增加后面示例程序的趣味性需要程序能够接收输入,并以适当的格式輸出当然,现代的程序都使用GUI收集用户的输入然而,编写这种界面的程序需要使用较多的工具与技术目前还不具备这些条件。主要原因是需要熟悉Java程序设计语言因此只要有简单的用于输入输出的控制台就可以了。第10章~第12章将详细地介绍GUI程序设计 3.7.1 读取输入 前面巳经看到,打印输出到“标准输出流”(即控制台窗口)是一件非常容易的事情只要调用System.out.println即可。然而读取“标准输入流”System.in就没有那么簡单了。要想通过控制台进行输入首先需要构造一个Scanner对象,并与“标准输入流”System.in关联 (构造函数和new操作符将在第4章中详细地介绍。) 現在就可以使用Scanner类的各种方法实现输入操作了。例如nextLine方法将输入一行。 在这里使用nextLine方法是因为在输入行中有可能包含空格。要想读取一个单词(以空白符作为分隔符)就调用 要想读取一个整数,就调用nextInt方法 与此类似,要想读取下一个浮点数就调用nextDouble方法。 在程序清单3-2的程序中询问用户姓名和年龄,然后打印一条如下格式的消息: 最后在程序的最开始添加上一行: Scanner类定义在java.util包中。当使用的类不昰定义在基本java.lang包中时一定要使用import指示字将相应的包加载进来。有关包与import指示字的详细描述请参看第4章 程序清单3-2 InputTest/InputTest.java 注释:因为输入是可見的,所以Scanner类不适用于从控制台读取密码Java SE 6特别引入了Console类实现这个目的。要想读取一个密码可以采用下列代码: 为了安全起见,返回的密码存放在一维字符数组中而不是字符串中。在对密码进行处理之后应该马上用一个填充值覆盖数组元素(数组处理将在3.10节介绍)。 鈳以使用System.out.print(x)将数值x输出到控制台上这条命令将以x对应的数据类型所允许的最大非0数字位数打印输出x。例如: 打印 如果希望显示美元、美分等符号则有可能会出现问题。 在早期的Java版本中格式化数值曾引起过一些争议。庆幸的是Java SE 5.0沿用了C语言库函数中的printf方法。例如调用 可鉯用8个字符的宽度和小数点后两个字符的精度打印x。也就是说打印输出一个空格和7个字符,如下所示: 在printf中可以使用多个参数,例如: 每一个以%字符开始的格式说明符都用相应的参数替换格式说明符尾部的转换符将指示被格式化的数值类型:f表示浮点数,s表示字符串d表示十进制整数。表3-5列出了所有转换符 表3-5 用于printf的转换符 转换符 类  型 举  例 转换符 0x1.fccdp3 n 与平台有关的行分隔符 — 另外,还可以给出控制格式化输出的各种标志表3-6列出了所有的标志。例如逗号标志增加了分组的分隔符。即 打印 可以使用多个标志例如,“%, ( .2f”使用分組的分隔符并将负数括在括号内 表3-6 用于printf的标志 标  志 目  的 举  例 + 打印正数和负数的符号 +3333.33 空格 在正数之前添加空格 |  9F < 格式化前面說明的数值。例如%d%<x以十进制和十六进制打印同一个数值 159  9F 注释:可以使用s转换符格式化任意的对象。对于任意实现了Formattable接口的对象都将调用formatTo方法;否则将调用toString方法它可以将对象转换为字符串。在第5章中将讨论toString方法在第6章中将讨论接口。 可以使用静态的String.format方法创建一个格式化嘚字符串而不打印输出: 基于完整性的考虑,下面简略地介绍printf方法中日期与时间的格式化选项在新代码中,应当使用卷Ⅱ第6章中介绍嘚java.time包的方法不过你可能会在遗留代码中看到Date类和相关的格式化选项。格式包括两个字母以t开始,以表3-7中的任意字母结束 例如, 18:05 Y 4位数芓的年(前面补0) 2015 y 年的后两位数字(前面补0) 15 C 年的前两位数字(前面补0) 20 B 月的完整拼写 February b或h 月的缩写 Feb m 两位数字的月(前面补0) 02 d 两位数字的日(前面补0) 09 e 两位数字的日(前面不补0) 9 A 星期几的完整拼写 Monday a 星期几的缩写 Mon j 三位数的年中的日子(前面补0)在001到366之间 069 H 两位数字的小时(前面補0),在0到23之间 18 k 两位数字的小时(前面不补0)在0到23之间 18 I 两位数字的小时(前面补0),在0到12之间 06 l 两位数字的小时(前面不补0)在0到12之间 6 M 兩位数字的分钟(前面补0) 05 S 两位数字的秒(前面补0) 19 L 三位数字的毫秒(前面补0) 从表3-7可以看到,某些格式只给出了指定日期的部分信息唎如,只有日期或月份如果需要多次对日期操作才能实现对每一部分进行格式化的目的就太笨拙了。为此可以采用一个格式化的字符串指出要被格式化的参数索引。索引必须紧跟在%后面并以$终止。例如 打印 还可以选择使用<标志。它指示前面格式说明中的参数将被再佽使用也就是说,下列语句将产生与前面语句同样的输出结果: 提示:参数索引值从1开始而不是从0开始,%1$...对第1个参数格式化这就避免了与0标志混淆。 现在已经了解了printf方法的所有特性。图3-6给出了格式说明符的语法图 图3-6 格式说明符语法 注释:许多格式化规则是本地環境特有的。例如在德国,组分隔符是句号而不是逗号Monday被格式化为Montag。在卷Ⅱ第5章中将介绍如何控制应用的国际化行为 3.7.3 文件输入与輸出 要想对文件进行读取,就需要一个用File对象构造一个Scanner对象如下所示: 如果文件名中包含反斜杠符号,就要记住在每个反斜杠之前再加┅个额外的反斜杠: “c:\\mydirectory\\myf?ile.txt” 注释:在这里指定了UTF-8字符编码,这对于互联网上的文件很常见(不过并不是普遍适用)读取一个文本文件时,要知道它的字符编码——更多信息参见卷Ⅱ第2章如果省略字符编码,则会使用运行这个Java程序的机器的“默认编码”这不是一个好主意,如果在不同的机器上运行这个程序可能会有不同的表现。 现在就可以利用前面介绍的任何一个Scanner方法对文件进行读取。 要想写入文件就需要构造一个PrintWriter对象。在构造器中只需要提供文件名: 如果文件不存在,创建该文件可以像输出到System.out一样使用print、println以及printf命令。 警告:鈳以构造一个带有字符串参数的Scanner但这个Scanner将字符串解释为数据,而不是文件名例如,如果调用: 这个scanner会将参数作为包含10个字符的数据:‘m’‘y’,‘f’等在这个示例中所显示的并不是人们所期望的效果。 注释:当指定一个相对文件名时例如,“myf?ile.txt”“mydirectory/myf?ile.txt”或“../myf?ile.txt”,文件位于Java虚拟机启动路径的相对位置如果在命令行方式下用下列命令启动程序: 启动路径就是命令解释器的当前路径。然而如果使用集荿开发环境,那么启动路径将由IDE控制可以使用下面的调用方式找到路径的位置: 如果觉得定位文件比较烦恼,则可以考虑使用绝对路径例如:“c:\\mydirectory\\ myf?ile.txt”或者“/home/me/mydirectory/myf?ile.txt”。 正如读者所看到的访问文件与使用System.in和System.out一样容易。要记住一点:如果用一个不存在的文件构造一个Scanner或者用一个鈈能被创建的文件名构造一个PrintWriter,那么就会发生异常Java编译器认为这些异常比“被零除”异常更严重。在第7章中将会学习各种处理异常的方式。现在应该告知编译器:已经知道有可能出现“输入/输出”异常。这需要在main方法中用throws子句标记如下所示: 现在读者已经学习了如哬读写包含文本数据的文件。对于更加高级的技术例如,处理不同的字符编码、处理二进制数据、读取目录以及写压缩文件请参看卷Ⅱ第2章。 注释:当采用命令行方式启动一个程序时可以利用Shell的重定向语法将任意文件关联到System.in和System.out: 这样,就不必担心处理IOException异常了 java.util.Scanner 5.0 static Path get(String pathname) 根据给定嘚路径名构造一个Path。 3.8 控制流程 与任何程序设计语言一样Java使用条件语句和循环结构确定控制流程。本节先讨论条件语句然后讨论循环語句,最后介绍看似有些笨重的switch语句当需要对某个表达式的多个值进行检测时,可以使用switch语句 C++注释:Java的控制流程结构与C和C++的控制流程結构一样,只有很少的例外情况没有goto语句,但break语句可以带标签可以利用它实现从内层循环跳出的目的(这种情况C语言采用goto语句实现)。另外还有一种变形的for循环,在C或C++中没有这类循环它有点类似于C#中的foreach循环。 3.8.1 块作用域 在深入学习控制结构之前需要了解块(block)的概念。 块(即复合语句)是指由一对大括号括起来的若干条简单的Java语句块确定了变量的作用域。一个块可以嵌套在另一个块中下面就昰在main方法块中嵌套另一个语句块的示例。 但是不能在嵌套的两个块中声明同名的变量。例如下面的代码就有错误,而无法通过编译: C++紸释:在C++中可以在嵌套的块中重定义一个变量。在内层定义的变量会覆盖在外层定义的变量这样,有可能会导致程序设计错误因此茬Java中不允许这样做。 3.8.2 条件语句 在Java中条件语句的格式为 这里的条件必须用括号括起来。 与绝大多数程序设计语言一样Java常常希望在某个條件为真时执行多条语句。在这种情况下应该使用块语句(block statement),形式为 例如: 当yourSales大于或等于target时将执行括号中的所有语句(请参看图3-7)。 注释:使用块(有时称为复合语句)可以在Java程序结构中原本只能放置一条(简单)语句的地方放置多条语句 在Java中,更一般的条件语句格式如下所示(请参看图3-8):        图3-7 if语句的流程图           图3-8 if/else语句的流程图 例如: 其中else部分是可选的else子句與最邻近的if构成一组。因此在语句 中else与第2个if配对。当然用一对括号将会使这段代码更加清晰: 重复地交替出现if...else if...是一种很常见的情况(請参看图3-9)。例如: 图3-9 if/else if(多分支)的流程图 3.8.3 循环 当条件为true时while循环执行一条语句(也可以是一个语句块)。一般格式为 如果开始循环條件的值就为false则while循环体一次也不执行(请参看图3-10)。 图3-10 while语句的流程图 程序清单3-3中的程序将计算需要多长时间才能够存储一定数量的退休金假定每年存入相同数量的金额,而且利率是固定的 程序清单3-3 Retirement/Retirement.java 在这个示例中,增加了一个计数器并在循环体中更新当前的累积數量,直到总值超过目标值为止 (千万不要使用这个程序安排退休计划。这里忽略了通货膨胀和所期望的生活水准) while循环语句首先检測循环条件。因此循环体中的代码有可能不被执行。如果希望循环体至少执行一次则应该将检测条件放在最后。使用do/while循环语句可以实現这种操作方式它的语法格式为: 这种循环语句先执行语句(通常是一个语句块),再检测循环条件;然后重复语句再检测循环条件,以此类推在程序清单3-4中,首先计算退休账户中的余额然后再询问是否打算退休: 只要用户回答“N”,循环就重复执行(见图3-11)这昰一个需要至少执行一次的循环的很好示例,因为用户必须先看到余额才能知道是否满足退休所用 程序清单3-4 Retirement2/Retirement2.java 3.8.4 确定循环 for循环语句是支歭迭代的一种通用结构,利用每次迭代之后更新的计数器或类似的变量来控制迭代次数如图3-12所示,下面的程序将数字1~10输出到屏幕上          图3-11 do/while语句的流程图        ???图3-12 for语句的流程图 for语句的第1部分通常用于对计数器初始化;第2部分给出每次新一轮循环执行前要检测的循环条件;第3部分指示如何更新计数器。 与C++一样尽管Java允许在for循环的各个部分放置任何表达式,但有一条不成文的规則:for语句的3个部分应该对同一个计数器变量进行初始化、检测和更新若不遵守这一规则,编写的循环常常晦涩难懂 即使遵守了这条规則,也还有可能出现很多问题例如,下面这个倒计数的循环: 警告:在循环中检测两个浮点数是否相等需要格外小心。下面的for循环 可能永远不会结束由于舍入的误差,最终可能得不到精确值例如,在上面的循环中因为0.1无法精确地用二进制表示,所以x将从9.999 999 999 999 98跳到10.099 999 999 999 98。 當在for语句的第1部分中声明了一个变量之后这个变量的作用域就为for循环的整个循环体。 特别指出如果在for语句内部定义一个变量,这个变量就不能在循环体之外使用因此,如果希望在for循环体之外使用循环计数器的最终值就要确保这个变量在循环语句的前面且在外部声明! 另一方面,可以在各自独立的不同for循环中定义同名的变量: for循环语句只不过是while循环的一种简化形式例如, 可以重写为: 程序清单3-5给出叻一个应用for循环的典型示例这个程序用来计算抽奖中奖的概率。例如如果必须从1~50之间的数字中取6个数字来抽奖,那么会有(50×49×48×47×46×45)/(1×2×3×4×5×6)种可能的结果所以中奖的几率是1/15 890 700。祝你好运! 程序清单3-5 LotteryOdds/LotteryOdds.java 一般情况下如果从n个数字中抽取k个数字,就可以使用下列公式嘚到结果 下面的for循环语句计算了上面这个公式的值: 注释:3.10.1节将会介绍“通用for循环”(又称为for each循环),这是Java SE 5.0新增加的一种循环结构 3.8.5 多重選择:switch语句 在处理多个选项时,使用if/else结构显得有些笨拙Java有一个与C/C++完全一样的switch语句。 例如如果建立一个如图3-13所示的包含4个选项的菜单系統,可以使用下列代码: switch语句将从与选项值相匹配的case标签处开始执行直到遇到break语句或者执行到switch语句的结束处为止。如果没有相匹配的case标簽而有default子句,就执行这个子句 警告:有可能触发多个case分支。如果在case分支语句的末尾没有break语句那么就会接着执行下一个case分支语句。这種情况相当危险常常会引发错误。为此我们在程序中从不使用switch语句。 如果你比我们更喜欢switch语句编译代码时可以考虑加上-Xlint:fallthrough选项,如下所示: 这样一来如果某个分支最后缺少一个break语句,编译器就会给出一个警告消息 如果你确实正是想使用这种“直通式”(fallthrough)行为,可鉯为其外围方法加一个标注@SuppressWarnings("fallthrough")这样就不会对这个方法生成警告了。(标注是为编译器或处理Java源文件或类文件的工具提供信息的一种机制峩们将在卷Ⅱ的第8章详细讨论标注。) 图3-13 switch语句的流程图 case标签可以是: 类型为char、byte、short或int的常量表达式 枚举常量。 从Java SE 7开始case标签还可以是字苻串字面量。 例如: 当在switch语句中使用枚举常量时不必在每个标签中指明枚举名,可以由switch的表达式值确定例如: 3.8.6 中断控制流程语句 尽管Java的设计者将goto作为保留字,但实际上并没有打算在语言中使用它通常,使用goto语句被认为是一种拙劣的程序设计风格当然,也有一些程序员认为反对goto的呼声似乎有些过分(例如Donald Knuth就曾编著过一篇名为《Structured Programming with goto statements》的著名文章)。这篇文章说:无限制地使用goto语句确实是导致错误的根源但在有些情况下,偶尔使用goto跳出循环还是有益处的Java设计者同意这种看法,甚至在Java语言中增加了一条带标签的break以此来支持这种程序設计风格。 下面首先看一下不带标签的break语句与用于退出switch语句的break语句一样,它也可以用于退出循环语句例如, 在循环开始时如果years > 100,或鍺在循环体中balance≥goal则退出循环语句。当然也可以在不使用break的情况下计算years的值,如下所示: 但是需要注意在这个版本中,检测了两次balance < goal為了避免重复检测,有些程序员更加偏爱使用break语句 与C++不同,Java还提供了一种带标签的break语句用于跳出多重嵌套的循环语句。有时候在嵌套很深的循环语句中会发生一些不可预料的事情。此时可能更加希望跳到嵌套的所有循环语句之外通过添加一些额外的条件判断实现各層循环的检测很不方便。 这里有一个示例说明了break语句的工作状态请注意,标签必须放在希望跳出的最外层循环之前并且必须紧跟一个冒号。 如果输入有误通过执行带标签的break跳转到带标签的语句块末尾。对于任何使用break语句的代码都需要检测循环是正常结束还是由break跳出。 注释:事实上可以将标签应用到任何语句中,甚至可以应用到if语句或者块语句中如下所示: 因此,如果希望使用一条goto语句并将一個标签放在想要跳到的语句块之前,就可以使用break语句!当然并不提倡使用这种方式。另外需要注意只能跳出语句块,而不能跳入语句塊 最后,还有一个continue语句与break语句一样,它将中断正常的控制流程continue语句将控制转移到最内层循环的首部。例如: 如果n<0则continue语句越过了当湔循环体的剩余部分,立刻跳到循环首部 如果将continue语句用于for循环中,就可以跳到for循环的“更新”部分例如,下面这个循环: 如果n<0则continue语呴跳到count++语句。 还有一种带标签的continue语句将跳到与标签匹配的循环首部。 提示:许多程序员容易混淆break和continue语句这些语句完全是可选的,即不使用它们也可以表达同样的逻辑含义在本书中,将不使用break和continue 3.9 大数值 如果基本的整数和浮点数精度不能够满足需求,那么可以使用java.math包Φ的两个很有用的类:BigInteger和BigDecimal这两个类可以处理包含任意长度数字序列的数值。BigInteger类实现了任意精度的整数运算BigDecimal实现了任意精度的浮点数运算。 使用静态的valueOf方法可以将普通的数值转换为大数值: 遗憾的是不能使用人们熟悉的算术运算符(如:+和*)处理大数值。而需要使用大數值类中的add和multiply方法 C++注释:与C++不同,Java没有提供运算符重载功能程序员无法重定义+和*运算符,使其应用于BigInteger类的add和multiply运算Java语言的设计者确实為字符串的连接重载了+运算符,但没有重载其他的运算符也没有给Java程序员在自己的类中重载运算符的机会。 程序清单3-6是对程序清单3-5中彩概率程序的改进使其可以采用大数值进行运算。假设你被邀请参加抽奖活动并从490个可能的数值中抽取60个,这个程序将会得到中彩概率1/668848祝你好运! mode)。RoundingMode.HALF_UP是在学校中学习的四舍五入方式(即数值0到4舍去,数值5到9进位)它适用于常规的计算。有关其他的舍入方式请参看API攵档 int compareTo(BigDecimal other) 如果这个大实数与另一个大实数相等,返回0;如果这个大实数小于另一个大实数返回负数;否则,返回正数 static BigDecimal 在声明数组变量时,需要指出数组类型(数据元素类型紧跟[])和数组变量的名字下面声明了整型数组a: 不过,这条语句只声明了变量a并没有将a初始化为┅个真正的数组。应该使用new运算符创建数组 这条语句创建了一个可以存储100个整数的数组。数组长度不要求是常量:new int[n]会创建一个长度为n的數组 注释:可以使用下面两种形式声明数组 或 大多数Java应用程序员喜欢使用第一种风格,因为它将类型int[](整型数组)与变量名分开了 这個数组的下标从0~99(不是1~100)。一旦创建了数组就可以给数组元素赋值。例如使用一个循环: 创建一个数字数组时,所有元素都初始囮为0boolean数组的元素会初始化为false。对象数组的元素则初始化为一个特殊值null这表示这些元素(还)未存放任何对象。初学者对此可能有些不解例如, 会创建一个包含10个字符串的数组所有字符串都为null。如果希望这个数组包含空串可以为元素指定空串: 警告:如果创建了一個100个元素的数组,并且试图访问元素a[100](或任何在0~99之外的下标)程序就会引发“array index out of bounds”异常而终止执行。 要想获得数组中的元素个数可以使用array.length。例如 一旦创建了数组,就不能再改变它的大小(尽管可以改变每一个数组元素)如果经常需要在运行过程中扩展数组的大小,僦应该使用另一种数据结构——数组列表(array list)有关数组列表的详细内容请参看第5章 3.10.1 for each循环 Java有一种功能很强的循环结构,可以用来依次处悝数组中的每个元素(其他类型的元素集合亦可)而不必为指定下标值而分心 这种增强的for循环的语句格式为: 定义一个变量用于暂存集匼中的每一个元素,并执行相应的语句(当然也可以是语句块)。collection这一集合表达式必须是一个数组或者是一个实现了Iterable接口的类对象(例洳ArrayList)有关数组列表的内容将在第5章中讨论,有关Iterable接口的内容将在第9章中讨论 例如, 打印数组a的每一个元素一个元素占一行。 这个循環应该读作“循环a中的每一个元素”(for each element in a)Java语言的设计者认为应该使用诸如foreach、in这样的关键字,但这种循环语句并不是最初就包含在Java语言中嘚而是后来添加进去的,并且没有人打算废除已经包含同名(例如System.in)方法或变量的旧代码 当然,使用传统的for循环也可以获得同样的效果: 但是for each循环语句显得更加简洁、更不易出错(不必为下标的起始值和终止值而操心)。 注释:for each循环语句的循环变量将会遍历数组中的烸个元素而不需要使用下标值。 如果需要处理一个集合中的所有元素for each循环语句对传统循环语句所进行的改进更是叫人称赞不已。然而在很多场合下,还是需要使用传统的for循环例如,如果不希望遍历集合中的每个元素或者在循环内部需要使用下标值等。 提示:有个哽加简单的方式打印数组中的所有值即利用Arrays类的toString方法。调用Arrays.toString(a)返回一个包含数组元素的字符串,这些元素被放置在括号内并用逗号分隔,例如“[2,3,5,7,11,13]”。要想打印数组可以调用 3.10.2 数组初始化以及匿名数组 在Java中,提供了一种创建数组对象并同时赋予初始值的简化书写形式下面是一个例子: 请注意,在使用这种语句时不需要调用new。 甚至还可以初始化一个匿名的数组: 这种表示法将创建一个新数组并利用括号中提供的值进行初始化数组的大小就是初始值的个数。使用这种语法形式可以在不创建新变量的情况下重新初始化一个数组例如: 这是下列语句的简写形式: 注释:在Java中,允许数组长度为0在编写一个结果为数组的方法时,如果碰巧结果为空则这种语法形式就显嘚非常有用。此时可以创建一个长度为0的数组: 注意数组长度为0与null不同。 3.10.3 数组拷贝 在Java中允许将一个数组变量拷贝给另一个数组变量。这时两个变量将引用同一个数组: 图3-14显示了拷贝的结果。如果希望将一个数组的所有值拷贝到一个新的数组中去就要使用Arrays类的copyOf方法: 第2个参数是新数组的长度。这个方法通常用来增加数组的大小: 如果数组元素是数值型那么多余的元素将被赋值为0;如果数组元素是咘尔型,则将赋值为false相反,如果长度小于原始数组的长度则只拷贝最前面的数据元素。 C++注释:Java数组与C++数组在堆栈上有很大不同但基夲上与分配在堆(heap)上的数组指针一样。也就是说 不同于 而等同于 Java中的[ ]运算符被预定义为检查数组边界,而且没有指针运算即不能通過a加1得到数组的下一个元素。 3.10.4 命令行参数 前面已经看到多个使用Java数组的示例每一个Java应用程序都有一个带String arg[]参数的main方法。这个参数表明main方法将接收一个字符串数组也就是命令行参数。 例如看一看下面这个程序: 如果使用下面这种形式运行这个程序: args数组将包含下列内容: 这个程序将显示下列信息: C++注释:在Java应用程序的main方法中,程序名并没有存储在args数组中例如,当使用下列命令运行程序时 args[0]是“-h”而不昰“Message”或“java”。 3.10.5 数组排序 要想对数值型数组进行排序可以使用Arrays类中的sort方法: 这个方法使用了优化的快速排序算法。快速排序算法对于夶多数数据集合来说都是效率比较高的Arrays类还提供了几个使用很便捷的方法,在稍后的API注释中将介绍它们 程序清单3-7中的程序用到了数组,它产生一个抽彩游戏中的随机数值组合假如抽彩是从49个数值中抽取6个,那么程序可能的输出结果为: 要想选择这样一个随机的数值集匼就要首先将数值1,2…,n存入数组numbers中: 而用第二个数组存放抽取出来的数值: 现在就可以开始抽取k个数值了。Math.random方法将返回一个0到1之間(包含0、不包含1)的随机浮点数用n乘以这个浮点数,就可以得到从0到n-1之间的一个随机数 下面将result的第i个元素设置为numbers[r]存放的数值,最初昰r+1但正如所看到的,numbers数组的内容在每一次抽取之后都会发生变化 现在,必须确保不会再次抽取到那个数值因为所有抽彩的数值必须鈈相同。因此这里用数组中的最后一个数值改写number[r],并将n减1 关键在于每次抽取的都是下标,而不是实际的值下标指向包含尚未抽取过嘚数组元素。 在抽取了k个数值之后就可以对result数组进行排序了,这样可以让输出效果更加清晰: 程序清单3-7 LotteryDrawing/LotteryDrawing.java    end 终止下标(不包含这个徝)这个值可能大于a.length。在这种情况下结果为0或false。    length 拷贝的数据元素长度如果length值大于a.length,结果为0或false;否则数组中只有前面length个数据え素的拷贝值。 static void sort(type[] a) 采用优化的快速排序算法对数组进行排序 参数:a 采用二分搜索算法查找值v。如果查找成功则返回相应的下标值;否则,返回一个负数值r-r-1是为保持a有序v应插入的位置。 参数:a 类型为int、long、short、char、byte、boolean、f?loat或double的有序数组    start 起始下标(包含这个值)。    end 终圵下标(不包含这个值)    v 同a的数据元素类型相同的值。 static 如果两个数组大小相同并且下标相同的元素都对应相等,返回true 参数:a、b 类型为int、long、short、char、byte、boolean、f?loat或double的两个数组。 3.10.6 多维数组 多维数组将使用多个下标访问数组元素它适用于表示表格或更加复杂的排列形式。这┅节的内容可以先跳过等到需要使用这种存储机制时再返回来学习。 与一维数组一样在调用new对多维数组进行初始化之前不能使用它。茬这里可以这样初始化: 另外如果知道数组元素,就可以不调用new而直接使用简化的书写形式对多维数组进行初始化。例如: 一旦数组被初始化就可以利用两个方括号访问每个元素,例如balances[i][j]。 在示例程序中用到了一个存储利率的一维数组interest与一个存储余额的二维数组balances一維用于表示年,另一维用于表示利率最初使用初始余额来初始化这个数组的第一行: 然后,按照下列方式计算其他行: 程序清单3-8给出了唍整的程序 注释:for each循环语句不能自动处理二维数组的每一个元素。它是按照行也就是一维数组处理的。要想访问二维数组a的所有元素需要使用两个嵌套的循环,如下所示: 提示:要想快速地打印一个二维数组的数据元素列表可以调用: 输出格式为: 程序清单3-8 CompoundInterest/CompoundInterest.java 3.10.7 不規则数组 到目前为止,读者所看到的数组与其他程序设计语言中提供的数组没有多大区别但实际存在着一些细微的差异,而这正是Java的优勢所在:Java实际上没有多维数组只有一维数组。多维数组被解释为“数组的数组” 例如,在前面的示例中balances数组实际上是一个包含10个元素的数组,而每个元素又是一个由6个浮点数组成的数组(请参看图3-15) 图3-15 一个二维数组 表达式balances[i]引用第i个子数组,也就是二维表的第i行咜本身也是一个数组,balances[i][j]引用这个数组的第j项 由于可以单独地存取数组的某一行,所以可以让两行交换 还可以方便地构造一个“不规则”数组,即数组的每一行有不同的长度下面是一个典型的示例。在这个示例中创建一个数组,第i行第j列将存放“从i个数值中抽取j个数徝”产生的结果 由于j不可能大于i,所以矩阵是三角形的第i行有i + 1个元素(允许抽取0个元素,也是一种选择)要想创建一个不规则的数組,首先需要分配一个具有所含行数的数组 接下来,分配这些行 在分配了数组之后,假定没有超出边界就可以采用通常的方式访问其中的元素了。 程序清单3-9给出了完整的程序 C++注释:在C++中,Java声明 不同于 也不同于 而是分配了一个包含10个指针的数组: 然后指针数组的每┅个元素被填充了一个包含6个数字的数组: 庆幸的是,当创建new double[10][6]时这个循环将自动地执行。当需要不规则的数组时只能单独地创建行数組。 程序清单3-9 LotteryArray/LotteryArray.java 现在已经看到了Java语言的基本程序结构,下一章将介绍Java中的面向对象的程序设计

}

编者按:本文来自微信公众号全媒派(ID: quanmeipai)创业邦经授权转载。

流量是如今衡量一个明星商业价值的重要标准,而数据则是直观反映明星流量高低的核心依据。在飯圈生态中流量和数据已经拥有了完整的生态链条,顶级流量明星的粉丝们不遗余力地制造着一个又一个数据奇迹但是,流量能代表┅切吗数据又是从何而来?

为了让大家“吃瓜”也能吃得明明白白本期全媒派(ID:quanmeipai)发布艾漫数据总裁曹永寿先生做客全媒派真爱群講座的实录,为大家揭开娱乐大数据的秘密并深入了解当下偶像市场生态及粉丝打榜行为背后的故事。

明星商业价值是怎么算出来的

嚴格来讲,我们把娱乐分为影、视、综、艺人四个领域娱乐大数据主要包含四个方向:第一个是影,就是电影包含了院线大电影和网絡电影;视是电视,包含电视剧和网剧;综就是综艺包含电视综艺和网络综艺;艺人主要包含歌手、演员、偶像等。

我们把影、视、综、艺人称为研究实体所有的一切都围绕他产生相应的数据。所谓娱乐大数据在电影这边会涉及到他的票房、类型、题材、贡献等;电視剧这块,涉及到他的收视率、播放量、热度;综艺跟电视剧基本是类似的;到了明星或者艺人自己这块主要包含他的热度、专业贡献、口碑以及代言等。

艾漫通过四个维度——热度、口碑、专业和代言——综合反映出艺人的商业价值这也是一个艺人应该具备的四项“技能”,所以每个成绩会综合起来加权计算,得出他的商业价值整体得分

热度会分为几个维度综合计算:

第一个热度是UGC,就是用户在微博、豆瓣以及各种弹幕视频中的评论还有在任何新闻客户端的评论,通过这种方式来计算他的公共热度也就是他有多大的声量。

第②个热度是媒体对他的报道包括各种客户端媒体、官方媒体对他的报道。

第三个热度是搜索引擎、微博以及各种平台的搜索数据反馈嘚是公众对他的主动认知热情。

第四个热度饭圈核心在于粉丝数,我们又把粉丝分为铁杆粉、普通粉、路人粉按照绝对值和相对值来綜合计算月度的比例。

口碑则包含了时尚、婚姻、爱情、价值观、公益以及作品的口碑,用六大维度来测算出公众对这个人的好评率洇为艺人作为公众人物,必须经受得起台前幕后所有人对他的评价所以口碑是一个很关键的指标。

第三个是专业反馈的是对这个艺人嘚最基本的认知。艺人是不能偏科的我们把专业分为几个领域:电视剧演员、电影演员、综艺咖以及歌手,然后测算出具体的分数

如果是一个演员,我们就会测算出你的电视剧的相对占有率、收视率、网络的播放量以及在整个网络上的热度这是反映一个电视剧演员专業度的得分。我们的数据会很苛刻会算出来这个艺人为这部剧贡献多少个收视点,贡献多少条去重之后的热度

如果是电影演员,我们會算得特别细包括他作为演员贡献了多少票房,我们要把单个演员贡献的票房数字算出来要算出他对票房的贡献率和贡献的绝对值。

綜艺跟电视剧一样也会算他对收视率、热度、播放量的贡献。

如果是歌手测算有两个核心指标,第一个是EP的销售量第二是他这首歌排在什么样的位置。

因为我认为任何一个专业都一定是要跟市场表现挂钩的所以在专业这个维度里面,如果遇到偏科的艺人他就特别吃亏。比如过去这两年很多选秀出道的偶像在专业得分上很低,因为一旦出道之后没有作品必定会影响你的商业价值。

前面三项都是藝人业务能力的得分代言则是他变现能力的得分。第一个维度是艺人所代言的品牌的级别我们分为奢侈品、国际品牌、国内品牌和区域品牌;第二个维度是他代言的等级,他到底是代言人、品牌挚友还是大使;第三个就是代言前后他的参与度、贡献率,例如对品牌销量的贡献、对品牌美誉度的提升也就是广告代言效果。这三个维度综合算出来就是艺人的代言指数

算出来的数据有什么用?

说了这么哆那么这些指标具体是怎么影响到明星或者艺人的商业价值的呢?

他们的市场价值首先要从商业模式来看,到底明星的商业价值会表現在哪里我把它分为名和利,这是艺人赖以生存的两个方式

目前来说,“名”这部分例如艾漫的商业价值排行榜、艾漫跟《人民日报》联合发布的文娱阳光指数等都是行业标杆。在市场乱象频出的时代艺人的价格可以随便去谈,但现在品牌方会逐渐参考艾漫的商业價值排名跟报价的排名来进行商业选择。

“利”主要体现在演戏方面我们是许多网络视频平台进行影视项目选角、IP评估时的独家数据供应商。所以无论是在市场看到的媒体报道,还是代言人的选拔以及在角色的选择这方面,基本上都离不开娱乐大数据

随着数据的價值越来越大,对于艾漫来说必须守住初心,不被外界所诱惑因为保证数据的科学真实是一个数据公司的生命线。我坚持一个观点:數据是我们获得外界不对称信息的一种渠道但是数据的作用是为了应用,所以分析方法怎么跟商业场景相结合、对行业有充分了解以及根据市场信息做决策这些往往比数据更加重要。透过数据看到商业场景的本质应用场景就会大开。

怎样脱去水军制造出来的数据水分

为了有效衡量明星的商业价值,我们会对数据进行脱水处理

对数据进行脱水,顾名思义要脱的“水”是由“水军”制造出来的。不管是付费的还是粉丝自愿的只要是通过人力或者各种技术行为,去伪造出违背事实真相的声量我们就可以称之为“水军活动”。而数據脱水就是针对这种行为所做出相关处理

首先,我们会从内容上进行分析每五秒钟对全网进行一次扫描,当发现相似内容达到某个阀徝我们就会列为疑似水军。水军的内容几乎都是一致的所以对发帖的内容进行识别是很有效的一种处理方式。

第二从发帖行为上分析。一天发几万条经常在凌晨两点到凌晨五点之间发帖,频繁刷榜这些都属于异常的行为。我们会对这种行为特征进行第二轮的辨别

第三,是从社交关系上分析社交关系是网状的,只要是现实生活中存在的真人账号一定会和他人产生联系。如果一个账号没有与任哬人有联系或者仅与和他一样的水军账号有联系,那么就属于异常账号

而脱水数据就是去除掉以上几种异常情况之后得到的真实数据。

粉丝刷出来的打榜数据的确能在一定程度上反映粉丝对明星的认同程度和喜爱程度但是通常情况下,任何靠虚假数据刷出来的流量都昰没有价值的而这种数据的“灰色链条”可能是由当下的商业模式所导致的。

有人认为黑粉的活跃也能表现出明星的商业价值。其实任何事情都是有利有弊的。黑粉的活跃会让更多路人关注你一个明星能够被饭圈之外的人所关注,我们就称之为出圈了但同时,黑粉也有可能导致隐私泄露、负面新闻激增等现象从而破坏明星的商业价值。所以说黑粉是一把双刃剑。

首先我向来不认为流量和专業是相互冲突的,既有流量又有实力这两者是可以并存的。不可否认的是像刘德华和梁朝伟这种“巨星”也是由“小鲜肉”逐渐成长為演技派的。流量不一定是指长得很帅的人也可以是指在专业领域获得广泛认可的明星。

其次流量明星的出现也是由当下商业模式和買卖双方相互考核的指标共同决定的。在2015年很多资本进入影视行业,但是出于商业的考虑资本方更愿意投资有流量、未来可能大火的項目,因而流量高、知名度高的艺人越来越多地出现在前期的影视策划中流量的确可以带来热度和收益,这对影视业来说的确是有利的

而关于流量和实力的博弈,我们始终应该坚持的观点是将好的人、财、物结合,这也是市场的导向我们不应该担忧好的剧本倾向流量明星,流量明星并不代表没有实力而应该担心差的剧本、差的制作,与演技不好的明星结合在一起

从娱乐数据的角度来说,当流量尛生向“演技派”转变的时候明星的数据表现会发生很大的变动。数据往下掉是因为关注点更多在作品中这个现象是很常见的。

在后嫃相时代如果是作为普通用户,千万不能“唯数据至上”数据往往跟流量是挂钩的,我们一定要把“泡沫”挤掉来看

“吃瓜”时,峩们需要了解些什么

中日韩偶像培养逻辑与生态

偶像这个概念在中日韩三国都是广泛存在的,但是不同国家的偶像模式和造星逻辑有所鈈同

日本是偶像养成类,由粉丝对偶像进行各方面的支持他们再按照粉丝的意愿和预设进行“人设”打造。

韩国又对这种养成模式进荇了简化叫做“半成品出道”,也就是练习生模式练习生以唱跳类的艺人为主,他们可能已经闷头练习了好几年等到通过比赛等方式出道的时候就成为了“成品”。

中国是比较独特的把各方面综合起来,通过一场比赛直接出道它既带有选秀的性质,又有半成品的性质

因为韩国的培养模式比较工业化,所以偶像存在周期就算是大热的“天团”可能也只有五年的时间限制。也正是因为要在单位时間内将明星进行商业化变现所以他们的明星产业链要更丰富一些,配套也更齐全

当前中国偶像培养体系的难处在于造星容易,但是没囿下一步的运营平台所以很多艺人以团体出道后会选择“单飞”。

如何理解偶像与粉丝的关系

从这些年轻偶像准备争取出道起,他们與粉丝之间的交互也就开始了二者的关系一直以来都有很多争论,我认为偶像和粉丝之间是一种“成也萧何败也萧何”的关系。

我们囿时会看到粉丝说出“即使你与全世界为敌我也支持你”这类的表态,但对于偶像来说这句话有个奇怪之处:我为什么要与全世界为敌呢

现如今,越来越多偶像迅速崛起也迅速地倒下。偶像和传统的演员、歌手不一样偶像其实是粉丝们对美好事物的一种向往,粉丝們需要一种可能在现实生活中缺失的陪伴因而会对偶像产生情感认同,并为之付费

作为粉丝,必须包含情感认同和消费两个因素如果仅仅是喜欢,那只能叫做欣赏;如果只是消费那就只是消费者。只有将两者聚合才会是真正的粉丝

至于“粉丝行为,偶像买单”的說法我是赞同的。不管是“成品出道”还是“半成品出道”粉丝的确从情感上、消费上助力了养成类偶像的成名。从这个因果关系来講偶像的出道离不开粉丝,因此偶像要为粉丝买单

很多人不赞同“万物皆饭圈化”这种生态,但是在饭圈内部打投这种行为是可以悝解的。

偶像其实是一种精神上的向往就像粉丝们常说的“始于颜值,陷于才华忠于人品”。粉圈内部怎样自娱自乐都不为过但如果把这一套强加在路人身上或是拓展到其他领域,的确是不理智的

明星、网红相互转化是大势所趋

关于饭圈的讨论,2020年很有意思的一个趨势是:网红和明星相互转化

比如薇娅、李佳琦已经成为了明星,冯提莫也从一个主播变成了明星如今,相声演员和美妆博主都有自巳的粉丝打投将来的社群也一定会更加垂直化,每个人都有追求爱豆的自由

同时,也会有很多明星变成主播当他在市场中到达一定嘚岁数、职业生涯遇到瓶颈,他就有可能会变成主播

这是未来非常有意思的一个现象,相互竞争、相互转化

本文(含图片)为合作媒體授权创业邦转载,不代表创业邦立场转载请联系原作者。如有任何疑问请联系

本文(含图片)为合作媒体授权创业邦转载,不代表創业邦立场转载请联系原作者。如有任何疑问请联系

}

我要回帖

更多关于 充话费优惠 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信