基础的不能再基础的东西
1 | public static void main(String[] args) |
public:访问修饰符,它也是最宽松的,所有类可见。不写是default,同一包内可见,按严格类型划分它们中间还有个protected,最严格的是privat。
static:关键字。(全局或静态的意思,动态是final,值不给变,修饰的方法不可被重写或者继承)//Java语言没有全局变量的概念
其他影响:static和final都是附加的功能没有默认一说,静态只能调静态,动态调动态。
//final还不能被继承。
void:返回类型。//不是void的话你可以是int型啥的 但是要return同类型的
main:方法名。//可改
string[]:string类数组。//可改,甚至不是数组,但是这样连运行入口都没了。。
args:字符串型数组。//可改
1 | public class Debug02_go { |
如何调用同文件夹下的其他包的方法?
1 | package com.company.phase01; |
让我们从别处调用它
1 | package com.company.phase01; |
运行结果:
wzkang
呵呵
创建个栈
1 | Stack<Integer> stack = new Stack<>(); |
这里只是粗略写这些,详细的以后写。
Collection 方法接口
Map是独立的接口,和collection是两条路。
Collection接口是 (java.util.Collection)是Java集合类的顶级接口之一。
Collection 接口有 3 种子类型集合: List、Set 和 Queue,再下面是一些抽象类,最后是具体实现类,常用的有 ArrayList、LinkedList、HashSet、LinkedHashSet、ArrayBlockingQueue等。
别的文章写到:Collection、List、Set和Map都是接口(Interface),不是具体的类实现。
List lst = new ArrayList(); 这是我们平常经常使用的创建一个新的List的语句,在这里, List是接口,ArrayList才是具体的类。
懂了,接口是接口,类不一致说明可能是其下子类?
set 集合
Set集合类似于一个罐子,程序可以依次把多个对象“丢进”Set集合,但它是无序的。实际上Set就是Collection只是行为略有不同。
Set集合不允许包含相同的元素,如果试图把两个相同元素加入同一个Set集合中,则添加操作失败,add()方法返回false,且新元素不会被加入。
为什么不能重复存在相同元素?
因为Set是在 HashMap的基础上来实现的,又因为HashMap的key是不能有重复的。
常用的方法:
add() 向集合添加元素
clear() 去掉集合中所有的元素
contains() 判断集合中是否包含某一个元素
isEmpty() 判断集合是否为空
iterator() 主要用于递归集合,返回一个iterator()对象
size() 返回集合的大小
HashSet:
1 | Set<Integer> set = new HashSet<>(); |
我就纳闷了,这不和TreeSet没差别吗?
1.不能保证元素的排列顺序,顺序有可能发生变化
2.不是同步的
3.集合元素可以是null,但只能放入一个null
TreeSet是根据二叉树实现的,不能放null,HashSet是根据hashCode的值进行equals比较的。
摘自网上他人的博客记录。
LinkedHashSet:
HashSet的一个子类,一个链表。
TreeSet:
SortedSet的子类,它不同于HashSet的根本就是TreeSet是有序的。它是通过SortedMap来实现的。
TreeSet是基于TreeMap实现的,TreeSet中的元素支持2种排序方式,自然排序或者根据创建TreeSet时提供的Comparator进行排序,这取决于使用的构造方法。
TreeSet是非同步的。 它的iterator 方法返回的迭代器是fail-fast的。
TreeSet会将里面的元素默认排序。
1 | public class TreeSet { |
其他杂七杂八测试
1 | test.removeAll(test);//删除所有元素 |
Set总结:
Set实现的基础是Map(HashMap)
Set中的元素是不能重复的,如果使用add(Object obj)方法添加已经存在的对象,则会覆盖前面的对象
如何创建个list列表?
1 | List<Integer> list = new ArrayList<>(); |
List:列表,同时要加载包。 //接口
Integer:里面存放的数据类型。 //类型
list:名字,可以改你喜欢的。
new 新建个 ArrayList<>(); //方法,哪怕是子类方法
ArrayList:数组列表。
<这里面在这可以被省略(不省略的话写前面<这里的东西>)>。
():可以不管,但是你想直接插入值可以在这里写。??好像不对啊先放着以后搞。
这就可以举一反三创别的东西了
将数组列表转换为数组的方法
Object[] s = list.toArray();//list搞出来默认就是object类型
Arrays.toString(s)//可以这样搞回来
———————-分割线———————
Strint[] s = list.toArray(new String[value])
String[] s = str.toArray(String[]::new);
value:length值
用第二、三种方法可以把list放到对应类型的数组里。
ps:其实用for强循环就行。。
———————-分割线———————
对上面Collection的衔接:
List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置,类似Java的数组。
Vector:
基于数组(Array)的List,其实就是封装了数组所不具备的一些功能方便我们使用,所以它难易避免数组的限制,同时性能也不可能超越数组。所以,在可能的情况下,我们要多运用数组。另外很重要的一点就是Vector是线程同步的(sychronized)的,这也是Vector和ArrayList 的一个的重要区别。
ArrayList
同Vector一样是一个基于数组上的链表,但是不同的是ArrayList不是同步的。所以在性能上要比Vector好一些,但是当运行到多线程环境中时,可需要自己在管理线程的同步问题。
LinkedList:
LinkedList不同于前面两种List,它不是基于数组的,所以不受数组性能的限制。
它每一个节点(Node)都包含两方面的内容:
1.节点本身的数据(data);
2.下一个节点的信息(nextNode)。
所以当对LinkedList做添加,删除动作的时候就不用像基于数组的ArrayList一样,必须进行大量的数据移动。只要更改nextNode的相关信息就可以实现了,这是LinkedList的优势。
List总结:
所有的List中只能容纳单个不同类型的对象组成的表,而不是Key-Value键值对。例如:[ tom,1,c ]
所有的List中可以有相同的元素,例如Vector中可以有 [ tom,koo,too,koo ]
所有的List中可以有null元素,例如[ tom,null,1 ]
基于Array的List(Vector,ArrayList)适合查询,而LinkedList 适合添加,删除操作
Queue 队列
队列通常(但并非一定)以 FIFO(先进先出)的方式排序各个元素。
不过优先级队列和 LIFO (后进先出)队列(或堆栈)例外。
LinkedList(链表)类实现了Queue接口,因此我们可以把LinkedList当成Queue来用。
Java Queue接口是Java Collections Framework的成员。
Queue 实现通常不允许插入 null 元素。
1 | Queue<String> queue = new LinkedList<>(); |
Queue中add()和offer()都是用来向队列添加一个元素。
在容量已满的情况下,add() 方法会抛出IllegalStateException异常,offer() 方法只会返回 false 。
1 | Queue<String> queue = new LinkedList<>(); |
Queue 中 element() 和 peek()都是用来返回队列的头元素,不删除。
在队列元素为空的情况下,element() 方法会抛出NoSuchElementException异常,peek() 方法只会返回 null。
1 | Queue<String> queue = new LinkedList<>(); |
remove() 和 poll() 方法都是从队列中删除第一个元素。如果队列元素为空,调用remove() 的行为与 Collection 接口的版本相似会抛出异常,但是新的 poll() 方法在用空集合调用时只是返回 null。
Java interface接口初步使用
先来了解抽象的概念:absttact
1 | package com.company.phase04; |
抽象类没有实体概念,不能搞static,否则就实例化了。
你问实例化对象是什么?
1 | public class Student { //学生类 |
再来个测试类
1 | public class Test { |
1.以this.name=name;为例,this.name 表示调用成员变量name,后面的name表示形参的值,即我们在测试类中赋的值。
2.倘若直接在构造方法内部给this.name赋值,如this.name=”张三”,则优先执行在构造器内部赋的值。此时结果就是张三,而不是汤姆猫了。
3.成员变量有默认值,引用类型是null,值类型是0,布尔类型是false。
回到正题(abstract、interface)
如果一个类中至少有一个抽象方法,那么这个类一定是抽象类,但反之则不然。也就是说一个抽象类中可以没有抽象方法。这样做的目的是为了此类不能被实例化。
如果一个类继承了一个抽象类,那么它必须全部覆写抽象类中的抽象方法,当然也可以不全部覆写,如果不覆写全部抽象方法则这个子类也必须是抽象类(这样做就无意义了)。
理解了以上观点后再看看Interfac,它也就是一个抽象类型,是抽象方法的集合,接口通常以intrface来声明。
一个类通过继承接口的方式,从而来继承接口的抽象方法。
接口并不是类,编写接口的方式和类很相似,但是它们属于不同的概念。类描述对象的属性和方法。接口则包含类要实现的方法。
除非实现接口的类是抽象类,否则该类要定义接口中的所有方法。//abstract
接口无法被实例化,但是可以被实现。一个实现接口的类,必须实现接口内所描述的所有方法,否则就必须声明为抽象类。另外,在 Java 中,接口类型可用来声明一个变量,他们可以成为一个空指针,或是被绑定在一个以此接口实现的对象。
接口与类相似点
一个接口可以有多个方法。
接口文件保存在 .java 结尾的文件中,文件名使用接口名。
接口的字节码文件保存在 .class 结尾的文件中。
接口相应的字节码文件必须在与包名称相匹配的目录结构中。
接口和类的区别
接口不能用于实例化对象。
接口没有构造方法。
接口中所有的方法必须是抽象方法,Java 8 之后 接口中可以使用 default 关键字修饰的非抽象方法。
接口不能包含成员变量,除了 static 和 final 变量。
接口不是被类继承了,而是要被类实现。
接口支持多继承。//xxxx extend x,y,z
接口特性
接口中每一个方法也是隐式抽象的,接口中的方法会被隐式的指定为 public abstract(只能是 public abstract,其他修饰符都会报错),不写也是默认这个的。
接口中可以含有变量,但是接口中的变量会被隐式的指定为 public static final 变量(并且只能是 public,用 private 修饰会报编译错误)。
接口中的方法是不能在接口中实现的,只能由实现接口的类来实现接口中的方法。
接口和抽象类的区别
抽象类中的方法可以有方法体,就是能实现方法的具体功能,但是接口中的方法不行。
抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是 public static final 类型的。
接口中不能含有静态代码块以及静态方法(用 static 修饰的方法),而抽象类是可以有静态代码块和静态方法。
一个类只能继承一个抽象类,而一个类却可以实现多个接口。
1 | //先看接口 |
下面是实例
1 | package com.company.phase03; |
instanceof 关键字用法
instanceof 是 Java 的一个二元操作符,类似于 ==,>,< 等操作符。
它的作用是测试它左边的对象是否是它右边的类的实例,返回 boolean 的数据类型。
1 | package com.company.phase05; |
运行结果:
[]对象是ArrayList类的实例。
泛型讲解
先看下面这个实例
1 | public class bala { |
首先,泛型只在编译阶段有效;
其次,泛型,即“参数化类型”。
顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),
然后在使用/调用时传入具体的类型(类型实参)。
泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。也就是说在泛型使用过程中,
操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。
总结:泛型类型在逻辑上看以看成是多个不同的类型,实际上都是相同的基本类型。
来看看实例就一目了然
1 | package com.company.phase05; |
T泛型在编译的时候没问题,但是运行的时候它的类型是被确认的,可以是在外部被确认。
来看看泛型接口怎么使用。
1 | package com.company.phase05; |
运行结果:3个字符串内容随机出一个
123