首页 文章 精选 留言 我的

精选列表

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

【Java入门提高篇】Day15 Java泛型再探——泛型通配符及上下边界

上篇文章中介绍了泛型是什么,为什么要使用泛型以及如何使用泛型,相信大家对泛型有了一个基本的了解,本篇将继续讲解泛型的使用,让你对泛型有一个更好的掌握和更深入的认识。 上篇中介绍完泛型之后,是不是觉得泛型挺好用的?既消除了Object的不安全类型转化,又可以很方便的进行类型对象的存取,但是,等一下,有没有考虑到这样的情况。 我们先定义一个水果类: public class Fruit { private String name; public Fruit(String name){ this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } } 然后再定义一个苹果类: public class Apple extends Fruit{ public Apple(String name) { super(name); } } 接下来定义一个泛型容器: public class GenericHolder<T> { private T obj; public GenericHolder(){} public GenericHolder(T obj){ this.obj = obj; } public T getObj() { return obj; } public void setObj(T obj) { this.obj = obj; } } 接下来开始我们的测试: public class Test { /** * 吃水果 * @param fruitHolder */ public static void eatFruit(GenericHolder<Fruit> fruitHolder){ System.out.println("我正在吃 " + fruitHolder.getObj().getName()); } public static void main(String args[]){ //这是一个贴了水果标签的袋子 GenericHolder<Fruit> fruitHolder = new GenericHolder<Fruit>(); //这是一个贴了苹果标签的袋子 GenericHolder<Apple> appHolder = new GenericHolder<Apple>(); //这是一个水果 Fruit fruit = new Fruit("水果"); //这是一个苹果 Apple apple = new Apple("苹果"); //现在我们把水果放进去 fruitHolder.setObj(fruit); //调用一下吃水果的方法 eatFruit(fruitHolder); //贴了水果标签的袋子放水果当然没有问题 //现在我们把水果的子类——苹果放到这个袋子里看看 fruitHolder.setObj(apple); //同样是可以的,其实这时候会发生自动向上转型,apple向上转型为Fruit类型后再传入fruitHolder中 //但不能再将取出来的对象赋值给redApple了 //因为袋子的标签是水果,所以取出来的对象只能赋值给水果类的变量 //无法通过编译检测 redApple = fruitHolder.getObj(); eatFruit(fruitHolder); //放苹果的标签,自然只能放苹果 appHolder.setObj(apple); // 这时候无法把appHolder 传入eatFruit // 因为GenericHolder<Fruit> 和 GenericHolder<Apple>是两种不同的类型 // eatFruit(appHolder); } } 运行结果: 我正在吃 水果 我正在吃 苹果 在这里,我们往eatFruit方法里传入fuitHolder的时候,是可以正常编译的,但是如果将appHolder传入,就无法通过编译了,因为作为参数时,GenericHolder<Fruit> 和 GenericHolder<Apple>是两种不同的类型,所以无法通过编译,那么问题来了,如果我想让eatFruit方法能同时处理GenericHolder<Fruit> 和 GenericHolder<Apple>两种类型怎么办?而且这也是很合理的需求,毕竟Apple是Fruit的子类,能吃水果,为啥不能吃苹果???如果要把这个方法重载一次,未免也有些小题大做了(而且事实上也无法通过编译,具体原因之后会有说明)。 在代码的逻辑里: 苹果 IS-A 水果 装苹果的盘子 NOT-IS-A 装水果的盘子 这个时候,泛型的边界符就有它的用武之地了。我们先来看效果: public class Test { /** * 吃水果 * @param fruitHolder */ public static void eatFruit(GenericHolder<? extends Fruit> fruitHolder){ System.out.println("我正在吃 " + fruitHolder.getObj().getName()); } public static void main(String args[]){ //这是一个贴了水果标签的袋子 GenericHolder<Fruit> fruitHolder = new GenericHolder<Fruit>(); //这是一个贴了苹果标签的袋子 GenericHolder<Apple> appHolder = new GenericHolder<Apple>(); //这是一个水果 Fruit fruit = new Fruit("水果"); //这是一个苹果 Apple apple = new Apple("苹果"); //现在我们把水果放进去 fruitHolder.setObj(fruit); //调用一下吃水果的方法 eatFruit(fruitHolder); //放苹果的标签,自然只能放苹果 appHolder.setObj(apple); // 这时候可以顺利把appHolder 传入eatFruit eatFruit(appHolder); } } 运行结果: 我正在吃 水果 我正在吃 苹果 这里我们只是使用了一点小小的魔法,把参数类型改成了GenericHolder<? extends Fruit>,这样就能将GenericHolder<Apple>类型的参数顺利传入了,怎么样?很好用吧,这就是泛型的边界符,用<? extends Fruit>的形式表示。边界符的意思,自然就是定义一个边界,这里用?表示传入的泛型类型不是固定类型,而是符合规则范围的所有类型,用extends关键字定义了一个上边界,也就是说这里的?可以代表任何继承于Fruit的类型,你也许会问,为什么是上边界,好问题,一图胜千言: 从这个图可以很好的看出这个“上边界”的概念了吧。有上边界,自然有下边界,泛型里使用形如<? super Fruit>的方式使用下边界,此时,?只能代表Fruit及其父类。 (这两个图是抠过来的,不要骂我懒。) 这两种方式基本上解决了我们之前的问题,但是同时,也有一定的限制。 1.上界<? extends T>不能往里存,只能往外取 不要太疑惑,其实很好理解,因为编译器只知道容器里的是Fruit或者Fruit的子类,但不知道它具体是什么类型,所以存的时候,无法判断是否要存入的数据的类型与容器种的类型一致,所以会拒绝set操作。 2.下界<? super T>往外取只能赋值给Object变量,不影响往里存 因为编译器只知道它是Fruit或者它的父类,这样实际上是放松了类型限制,Fruit的父类一直到Object类型的对象都可以往里存,但是取的时候,就只能当成Object对象使用了。 所以如果需要经常往外读,则使用<? extends T>,如果需要经常往外取,则使用<? super T>。 至此,本篇讲解完毕,欢迎大家继续关注! 真正重要的东西,用眼睛是看不见的。

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

HBase编程 API入门系列之delete.deleteColumn和delete.deleteColumns区别(客户端而言)(4)

心得,写在前面的话,也许,中间会要多次执行,连接超时,多试试就好了。 delete.deleteColumn和delete.deleteColumns区别是: deleteColumn是删除某一个列簇里的最新时间戳版本。 delete.deleteColumns是删除某个列簇里的所有时间戳版本。 hbase(main):020:0>desc 'test_table' Table test_table is ENABLED test_table COLUMN FAMILIES DESCRIPTION {NAME => 'f', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'ROW', REPLICATION_SCOPE => '0', VERSIONS => '1', COMPRESSION => 'NONE', MIN_VERSIONS => '0', TTL => 'FOREVER', KEEP_DELETED_CELLS => 'FALSE', BLOCKSIZE => '65536', IN_MEMORY => 'false', BLOCKCACHE => 'true'} 1 row(s) in 0.2190 seconds hbase(main):021:0>scan 'test_table' ROW COLUMN+CELL row_01 column=f:col, timestamp=1478102698687, value=maizi row_01 column=f:name, timestamp=1478104345828, value=Andy row_02 column=f:name, timestamp=1478104477628, value=Andy2 row_03 column=f:name, timestamp=1478104823358, value=Andy3 3 row(s) in 0.2270 seconds hbase(main):022:0>scan 'test_table' ROW COLUMN+CELL row_01 column=f:col, timestamp=1478102698687, value=maizi row_01 column=f:name, timestamp=1478104345828, value=Andy row_02 column=f:name, timestamp=1478104477628, value=Andy2 row_03 column=f:name, timestamp=1478104823358, value=Andy3 3 row(s) in 0.1480 seconds hbase(main):023:0>scan 'test_table',{VERSIONS=>3} ROW COLUMN+CELL row_01 column=f:col, timestamp=1478102698687, value=maizi row_01 column=f:name, timestamp=1478104345828, value=Andy row_02 column=f:name, timestamp=1478104477628, value=Andy2 row_03 column=f:name, timestamp=1478104823358, value=Andy3 3 row(s) in 0.1670 seconds hbase(main):024:0> 1 package zhouls.bigdata.HbaseProject.Test1; 2 3 import javax.xml.transform.Result; 4 5 import org.apache.hadoop.conf.Configuration; 6 import org.apache.hadoop.hbase.HBaseConfiguration; 7 import org.apache.hadoop.hbase.TableName; 8 import org.apache.hadoop.hbase.client.Delete; 9 import org.apache.hadoop.hbase.client.Get; 10 import org.apache.hadoop.hbase.client.HTable; 11 import org.apache.hadoop.hbase.client.Put; 12 import org.apache.hadoop.hbase.util.Bytes; 13 14 public class HBaseTest { 15 public static void main(String[] args) throws Exception { 16 HTable table = new HTable(getConfig(),TableName.valueOf("test_table"));//表名是test_table 17 Put put = new Put(Bytes.toBytes("row_04"));//行键是row_04 18 put.add(Bytes.toBytes("f"),Bytes.toBytes("name"),Bytes.toBytes("Andy0"));//列簇是f,列修饰符是name,值是Andy0 19 // put.add(Bytes.toBytes("f2"),Bytes.toBytes("name"),Bytes.toBytes("Andy3"));//列簇是f2,列修饰符是name,值是Andy3 20 table.put(put); 21 table.close(); 22 23 // Get get = new Get(Bytes.toBytes("row_04")); 24 // get.addColumn(Bytes.toBytes("f1"), Bytes.toBytes("age"));如现在这样,不指定,默认把所有的全拿出来 25 // org.apache.hadoop.hbase.client.Result rest = table.get(get); 26 // System.out.println(rest.toString()); 27 // table.close(); 28 29 // Delete delete = new Delete(Bytes.toBytes("row_2")); 30 // delete.deleteColumn(Bytes.toBytes("f1"), Bytes.toBytes("email")); 31 // delete.deleteColumn(Bytes.toBytes("f1"), Bytes.toBytes("name")); 32 // table.delete(delete); 33 // table.close(); 34 35 36 // Delete delete = new Delete(Bytes.toBytes("row_03")); 37 // delete.deleteColumn(Bytes.toBytes("f"), Bytes.toBytes("name")); 38 // delete.deleteColumns(Bytes.toBytes("f"), Bytes.toBytes("name")); 39 // table.delete(delete); 40 // table.close(); 41 } 42 43 public static Configuration getConfig(){ 44 Configuration configuration = new Configuration(); 45 // conf.set("hbase.rootdir","hdfs:HadoopMaster:9000/hbase"); 46 configuration.set("hbase.zookeeper.quorum", "HadoopMaster:2181,HadoopSlave1:2181,HadoopSlave2:2181"); 47 return configuration; 48 } 49 } hbase(main):038:0>scan 'test_table' ROW COLUMN+CELL row_01 column=f:col, timestamp=1478102698687, value=maizi row_01 column=f:name, timestamp=1478104345828, value=Andy row_02 column=f:name, timestamp=1478104477628, value=Andy2 row_03 column=f:name, timestamp=1478123664884, value=Andy3 3 row(s) in 0.1910 seconds hbase(main):039:0>scan 'test_table' ROW COLUMN+CELL row_01 column=f:col, timestamp=1478102698687, value=maizi row_01 column=f:name, timestamp=1478104345828, value=Andy row_02 column=f:name, timestamp=1478104477628, value=Andy2 row_03 column=f:name, timestamp=1478123664884, value=Andy3 row_04 column=f:name, timestamp=1478123917775, value=Andy0 4 row(s) in 0.1310 seconds delete.deleteColumn和delete.deleteColumns区别是: deleteColumn是删除某一个列簇里的最新时间戳版本。 delete.deleteColumns是删除某个列簇里的所有时间戳版本。 1 package zhouls.bigdata.HbaseProject.Test1; 2 3 import javax.xml.transform.Result; 4 5 import org.apache.hadoop.conf.Configuration; 6 import org.apache.hadoop.hbase.HBaseConfiguration; 7 import org.apache.hadoop.hbase.TableName; 8 import org.apache.hadoop.hbase.client.Delete; 9 import org.apache.hadoop.hbase.client.Get; 10 import org.apache.hadoop.hbase.client.HTable; 11 import org.apache.hadoop.hbase.client.Put; 12 import org.apache.hadoop.hbase.util.Bytes; 13 14 public class HBaseTest { 15 public static void main(String[] args) throws Exception { 16 HTable table = new HTable(getConfig(),TableName.valueOf("test_table"));//表名是test_table 17 Put put = new Put(Bytes.toBytes("row_04"));//行键是row_04 18 put.add(Bytes.toBytes("f"),Bytes.toBytes("name"),Bytes.toBytes("Andy1"));//列簇是f,列修饰符是name,值是Andy0 19 // put.add(Bytes.toBytes("f2"),Bytes.toBytes("name"),Bytes.toBytes("Andy3"));//列簇是f2,列修饰符是name,值是Andy3 20 table.put(put); 21 table.close(); 22 23 // Get get = new Get(Bytes.toBytes("row_04")); 24 // get.addColumn(Bytes.toBytes("f1"), Bytes.toBytes("age"));如现在这样,不指定,默认把所有的全拿出来 25 // org.apache.hadoop.hbase.client.Result rest = table.get(get); 26 // System.out.println(rest.toString()); 27 // table.close(); 28 29 // Delete delete = new Delete(Bytes.toBytes("row_2")); 30 // delete.deleteColumn(Bytes.toBytes("f1"), Bytes.toBytes("email")); 31 // delete.deleteColumn(Bytes.toBytes("f1"), Bytes.toBytes("name")); 32 // table.delete(delete); 33 // table.close(); 34 35 36 // Delete delete = new Delete(Bytes.toBytes("row_03")); 37 // delete.deleteColumn(Bytes.toBytes("f"), Bytes.toBytes("name")); 38 // delete.deleteColumns(Bytes.toBytes("f"), Bytes.toBytes("name")); 39 // table.delete(delete); 40 // table.close(); 41 } 42 43 public static Configuration getConfig(){ 44 Configuration configuration = new Configuration(); 45 // conf.set("hbase.rootdir","hdfs:HadoopMaster:9000/hbase"); 46 configuration.set("hbase.zookeeper.quorum", "HadoopMaster:2181,HadoopSlave1:2181,HadoopSlave2:2181"); 47 return configuration; 48 } 49 } delete.deleteColumn和delete.deleteColumns区别是: deleteColumn是删除某一个列簇里的最新时间戳版本。 delete.deleteColumns是删除某个列簇里的所有时间戳版本。 本文转自大数据躺过的坑博客园博客,原文链接:http://www.cnblogs.com/zlslch/p/6156265.html,如需转载请自行联系原作者

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

《Android App开发入门:使用Android Studio 2.X开发环境》——2-6 输入字段 EditText 组件

2-6 输入字段 EditText 组件 除了按钮外,另一种常见的基本输入组件是EditText。 getText():获取用户输入的文字 EditText 组件的用途是让用户输入文字,在程序中可用 getText()获取用户输入的内容。 getText() 方法返回的是 Android SDK中定义的 Editable 类型的对象,因此要当字符串处理,必须再调用 toString() 方法进行转换。 setText():设置 TextView 显示的文字 如果要设置 TextView 组件上显示的文字,那么可以调用 TextView 类的 setText() 方法。若txv为TextView 类的对象,则设置让 TextView 显示“您好!”。 范例2-2: 加入 EditText 组件 在这个范例中使用 EditText 组件,并用程序

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

不是你无法入门自然语言处理(NLP),而是你没找到正确的打开方式

〇、序 之前一段时间,在结合深度学习做 NLP 的时候一直有思考一些问题,其中有一个问题算是最核心一个:究竟深度网络是怎么做到让各种 NLP 任务解决地如何完美呢?到底我的数据在 NN 中发什么了什么呢? 并且,不少的 terms like: 词向量、word embedding、分布式表示、word2vec、glove 等等,这一锅粥的名词术语分别代表什么,他们具体的关系是什么,他们是否处于平级关系? 出于对知识结构追求完整梳理的强迫症的老毛病,于是不停地查资料、思考、keep revolving…… 然后就感觉有一点小进展了。想到,不如将个人对其的理解,无论对错,先拿出来跟peer分享下,或许能交换出更有意义的东西呢? 整篇文章的构架是按照属于概念在逻辑上的先后大小顺序,一层一层一级一级地往下剖析、比较、说明。 另外说明下,here整

资源下载

更多资源
Mario

Mario

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

腾讯云软件源

腾讯云软件源

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

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册