欢迎关注我的公众号【软件大爆炸】
Java学习中的碎碎念
Java中易忽略的基础知识
Java面向对象基础
Java中的核心类
Java抽象类和接口
Java中的异常
Java中的泛型与集合
泛型类是引用类型,在堆内存中。
先看一段代码:
public class GenericDemo {
public static void main(String[] args) {
//这些类型参数在使用之前再进行指明。
Generic<String> strObj = new Generic<String>("欢迎关注公众号软件大爆炸!");
strObj.showDataType();
System.out.println(strObj.getData());
System.out.println("__________________________");
Generic<Double> dObj = new Generic<>(3.14);//这些类型参数在使用之前再进行指明。
dObj.showDataType();
System.out.println(dObj.getData());
System.out.println("____________________________");
Generic<Integer> iObj = new Generic<>();
iObj.setData(100);//这些类型参数在使用之前再进行指明。
iObj.showDataType();
System.out.println(iObj.getData());
}
}
class Generic<T>{//在编写代码时将数据类型定义成参数
private T data;
public Generic(){
}
public Generic(T data){
this.data = data;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public void showDataType(){
System.out.println("数据的类型是:"+data.getClass().getName());
}
}
数据的类型是:java.lang.String
欢迎关注公众号软件大爆炸!
__________________________
数据的类型是:java.lang.Double
3.14
____________________________
数据的类型是:java.lang.Integer
100
Process finished with exit code 0
接下来进行一些简单的说明:
class Generic
,使用时(即实例化时):Generic strObj = new Generic("欢迎关注公众号软件大爆炸!")
;或者Generic iObj = new Generic<>();iObj.setData(100);
。并且类型参数只是占位符,一般使用大写的“T”、“U”、“V”等作为类型参数。Generic dObj = new Generic<>(3.14);
,其实就等价于Generic dObj = new Generic(3.14);
下面介绍一下关于通配符:
通配符指 ?
public class NoWildcardDemo {
public static void main(String[] args) {
//Right
Generic<Object> gObbj = new Generic<Object>("Object");
myMethod(gObbj);
//Wrong
// Generic gint = new Generic<>(12);
// myMethod(gint);
//Wrong
// Generic gdbl = new Generic<>(3.145);
// myMethod(gdbl);
}
public static void myMethod(Generic<Object> g){
g.showDataType();
}
}
上面的代码出错的原因就在于没有使用通配符,所以只能使用Object
,如果将public static void myMethod(Generic
改成public static void myMethod(Generic> g)
,则不再报错,如下:
public class NoWildcardDemo {
public static void main(String[] args) {
//Right
Generic<Object> gObbj = new Generic<Object>("Object");
myMethod(gObbj);
//Right
Generic<Integer> gint = new Generic<>(12);
myMethod(gint);
//Right
Generic<Double> gdbl = new Generic<>(3.145);
myMethod(gdbl);
}
public static void myMethod(Generic<?> g){
g.showDataType();
}
}
数据的类型是:java.lang.String
数据的类型是:java.lang.Integer
数据的类型是:java.lang.Double
关于有界类型:
extends
关键字。super
关键字。public class UpBoundGenericDemo {
public static void main(String[] args) {
Generic<Integer> gint = new Generic<>(12);
myMethod(gint);
Generic<Double> gdbl = new Generic<>(3.14);
myMethod(gdbl);
Generic<String> gstr = new Generic<>("String");
//Wrong code
// myMethod(gstr);
}
public static void myMethod(Generic<? extends Number> g){
g.showDataType();
}
}
class UpBoundGeneric<T extends Number>{
private T data;
public UpBoundGeneric(){
}
public UpBoundGeneric(T dara){
this.data = data;
}
public T getData(){
return data;
}
public void setData(T data){
this.data = data;
}
public void showDataType(){
System.out.println("数据的类型是:"+data.getClass().getName());
}
}
数据的类型是:java.lang.Integer
数据的类型是:java.lang.Double
Process finished with exit code 0
下界的举例:
public class LowBoundGenericDemo {
public static void main(String[] args) {
Generic<String> gstr = new Generic<>("String类本身");
myMethod(gstr);
Generic<Integer> gint = new Generic<>(5);
//Wrong code
// myMethod(gint);
}
public static void myMethod(Generic<? super String> g){
g.showDataType();
}
}
数据的类型是:java.lang.String
Process finished with exit code 0
关于Java集合:
List的子类有ArrayList
和Vector
。两者的区别在于前者是非线程安全的,后者是线程安全的。
ArrayList
可以通过Collections
工具类手动变成线程安全的。
下面演示ArrayList的使用:
import java.util.ArrayList;
import java.util.Iterator;
public class ArrayListDemo {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
//向列表中添加元素
list.add("郑州");
list.add("北京");
list.add("上海");
list.add("深圳");
//使用for...each循环
for (String e: list
) {
System.out.println(e);
}
System.out.println("----------------------");
//使用迭代器遍历
Iterator<String> iterator = list.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
System.out.println("----------------------");
list.remove("上海");
for (String e: list
) {
System.out.println(e);
}
}
}
郑州
北京
上海
深圳
----------------------
郑州
北京
上海
深圳
----------------------
郑州
北京
深圳
Process finished with exit code 0
下面演示Vector的使用:
import java.util.Iterator;
import java.util.Stack;
import java.util.Vector;
public class VectorStackDemo {
public static void main(String[] args) {
Vector<Integer> v = new Vector<>();
for (int i = 0; i < 5; i++) {
v.add(i);
}
System.out.println("Vector中的元素:");
show(v.iterator());
System.out.println("-------------------------");
v.remove(2);
System.out.println("Vector删除后剩下的数据");
show(v.iterator());
System.out.println("-------------------------");
Stack<String> s = new Stack<>();
for (int i = 0; i <15; i++) {
s.push(String.valueOf(i));
}
System.out.println("Stack中的元素:");
show(s.iterator());
System.out.println("-----------------------");
System.out.println("Stack出栈:");
while(!s.isEmpty()){
System.out.println(s.pop());
}
}
public static void show(Iterator<?> iterator){
while (iterator.hasNext()) {
System.out.println(iterator.next());
}
}
}
Vector中的元素:
0 1 2 3 4
-------------------------
Vector删除后剩下的数据
0 1 3 4
-------------------------
Stack中的元素:
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14
-----------------------
Stack出栈:
14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
Process finished with exit code 0
关于Set集合:
Set接口常用的实现类包括 HashSet
、 TreeSet
和 Enum set
,这三个实现类各具特色
HashSet
是Set
接口的典型实现类,大多数使用Set
集合时都使用该实现类HashSet
使用Hash
算法来存储集合中的元素,具有良好的存、取以及可查找性。Treeset
采用Tree
“树”的数据结构来存储集合元素,因此可以保证集合中的元素处于排序状态。 Treeset
支持两种排序方式:自然排序和定制排序,默认情况下采用自然排序Enum Set
是一个专为枚举类设计的集合类,其所有元素必须是指定的枚举类型。Enum Set集合中的元素也是有序的,按照枚举值顺序进行排序。//HashSet Demo
import java.util.HashSet;
public class HashDemo {
public static void main(String[] args) {
//使用泛型HashSet
HashSet<String> hs = new HashSet<>();
//向HashSet中添加元素
hs.add("one");
hs.add("two");
hs.add("three");
//直接输出HashSet对象
System.out.println("开始的元素有:"+hs);
hs.remove("one");
System.out.println("剩下的元素是:"+hs);
}
}
开始的元素有:[one, two, three]
剩下的元素是:[two, three]
Process finished with exit code 0
//TreeSet Demo
import java.util.TreeSet;
public class TreeSetDemo {
public static void main(String[] args) {
TreeSet<String> hs = new TreeSet<>();
hs.add("1");
hs.add("4");
hs.add("2");
hs.add("3");
System.out.println(hs);
hs.remove("2");
System.out.println(hs);
}
}
[1, 2, 3, 4]
[1, 3, 4]
Process finished with exit code 0
import java.util.LinkedList;
public class LinkedListDemo {
public static void main(String[] args) {
LinkedList<String> names = new LinkedList<>();
//在队表末尾添加元素
names.offer("John");
//在队头添加元素
names.push("Bob");
//在队头添加元素
names.offerFirst("Lili");
//在队表末尾添加元素
names.offerLast("Steve");
System.out.println(names);
//访问栈顶元素(没有删除)
System.out.println("栈顶元素是:"+names.peekFirst());
//访问末尾元素(没有删除)
System.out.println("末尾元素是:"+names.peekLast());
}
}
[Lili, Bob, John, Steve]
栈顶元素是:Lili
末尾元素是:Steve
Process finished with exit code 0
import java.util.ArrayDeque;
public class ArrayDequeDemo {
public static void main(String[] args) {
ArrayDeque<String> queue = new ArrayDeque<>();
//在队尾添加元素
queue.offer("公众号软件大爆炸");
//在队头添加元素
queue.push("注重分享");
System.out.println(queue);
//从队首获取元素,同时获取的这个元素将从原队列删除
queue.poll();
System.out.println(queue);
}
}
[注重分享, 公众号软件大爆炸]
[公众号软件大爆炸]
Process finished with exit code 0
关于Map
HashMap
是基于哈希算法的Map
接口的实现类,该实现类提供所有映射操作,并允许使用nul
键和null
值,但不能保证映射的顺序,即是无序的映射集合;TreeMap
是基于“树”结构来存储的Map接口实现类,可以根据其键的自然顺序进行排序,或定制排序方式。首先演示HashMap
//HashMap Demo
import java.util.HashMap;
public class HashMapDemo {
public static void main(String[] args) {
HashMap<Integer, String> hm = new HashMap<>();
hm.put(1, "zhengzhou");
hm.put(2, "beijing");
hm.put(3, "shenzhen");
hm.put(4, "hangzhou");
hm.put(null, null);
System.out.println(hm.get(1));
System.out.println(hm.get(4));
hm.remove(1);
System.out.println(hm.get(1));
}
}
下面演示TreeMap
//TreeDemo
zhengzhou
hangzhou
null
Process finished with exit code 0
import java.util.TreeMap;
public class TreeMapDemo {
public static void main(String[] args) {
TreeMap<Integer, String> tm = new TreeMap<>();
tm.put(1, "zhengzhou");
tm.put(2, "beijing");
tm.put(3, "hangzhou");
//Wrong code//不允许使用Null键和null值
// tm.put(null, null);
System.out.println(tm.get(2));
tm.remove(2);
//Wright code
System.out.println(tm.get(2));
}
}
beijing
null
Process finished with exit code 0