Collection:
Alt+Shift+s get set 快捷键
集合顶级父接口,拥有很多子类,是一个动态数组
List: 有序的集合
List集合特有的的迭代器。ListIterator是Iterator的子接口。
如果使用List接口就可以有序的管理每个元素的位置(下标)
List:
//特有的方法,凡是可以操作角标的方法都是该体系特有的方法
增
add(index,element);
addAll(index,Collection);
删
remove(index);
改
set(index,element);
查
get(index);
subList(from,to);
listIterator();
ArrayList: Resizabke-array 是一个可改变长度的数组0
ArrayList: 底层的数据结构使用的是数组结构。 特点: 查询速度很快,但是增减速度稍慢
LinkedList: 底层使用的链表数据结构。 特点:增删速度很快,查询稍慢。
与数组唯一的区别在于动态(可改变长度)
api:
Collection c = new ArrayList();
/**
*1.add方法的参数类型是Object。 以便于接收任意类型对象。
*2.集合中存储的都是对象的引用(地址)
*/
class CollectionDome{
public static void main(String[]args){
//创建一个集合容器,使用collection 接口的子类。 ArrayList
ArrayList al = new ArrayList();
//添加元素
al.add("java01"); //add(Object obj)
al.add("java02");
al.add("java03");
al.add("java04");
//打印原集合
sop(al);
//删除元素
al.remove("java02");
//指定位置添加元素
al.add(1,"java08");
//修改元素
al.set(2,"java00");
//获取所有元素
for(int x=0;x<al.size();x++){
System.out.println("al("+X+")="+al.get(x));/
}
//获取个数,集合长度
sop("size:"+al.size());
//打印改变后的集合
sop(al);
//清空集合
al.clear();
//判断元素
sop("java03是否存在:"+al.contains("java03"));
}
public static void sop(Object obj){
System.out.println(obj);
}
}
每一个容器的数据结构不同,所以取出的动作细节也不一样,但是都有共性内容
那么这些内部类都符合一个规则,该规则是Iterator。
如何获取集合的取出对象呢?
通过一个对外提供的方法 Iterator();
set
set:元素是无序的(存入和取出的顺序是不一定一致的),元素不可以重复。
—HashSet: 底层数据结构是哈希表
HashSet是如何保证元素唯一性的呢?
通过元素的两个方法,hashcode和equals来完成。
如果元素的Hash Code值相同,才会判断equals是否为true
如果元素的Hash Code值不同,不会调用equals
注意: 对于判断元素是否存在,以及删除等操作,依赖的方法是元素的hashcode和equals方法
TreeSet:可以对Set集合中的元素进行排序
import java.util.HashMap;
import java.util.Map;
/**
* 给一个字符串,求出字符的出现次数
* 因为Map集合的key是唯一的(put两个相同的key时,后者会把前者value覆盖),所以这里可以用Map集合来做,
* 相同的字符就相当于key,每出现一次value就加一次
* 思路:
* 1.字符串转为字符数组
* 2.创建Map集合
* 3.遍历字符数组,取出一个字符,判断集合里是否有这个key,如果没有put到数组,如果有就value加一次
* 4.打印集合
* @author 华帅
*
*/
public class Dome {
public static void main(String[]args) {
findcount3("ababcbddjac");
}
public static void findcount3(String s) {
char[] cs = s.toCharArray(); //将字符串变为字符数组
Map<Character, Integer> mps =new HashMap<>();
for(char c : cs) { //循环遍历字符数组
char ch =c; //循环取出每一个字符
if (mps.containsKey(ch)) { //判断这个集合中是否有这个字符
int value =mps.get(ch)+1; //get(ch)获取key为ch的值,也就是这个字符的值,因为要计算这个字符出现的次数,所以要加一之后再重新put到集合中
mps.put(ch, value);
}else {
mps.put(ch, 1); //如果没有这个字符就put到这个集合中,值为1
}
}
System.out.println(mps);
}
泛型
泛型:JDK1.5版本以后出现的新特性。用于解决安全的问题,是一个安全机制。
好处:1.将运行时期出现的问题 ClassCastException,转移到了编译时期
方便与程序猿解决问题,让运行时期问题减少,安全
2.避免了强制转换的麻烦。
泛型格式: 通过< >来定义要操作的引用数据类型。
在使用Java提供的对象时,什么时候写泛型呢?
答: 通常在集合框架中常见 只要见到 < > 就要定义泛型
什么时候定义泛型类?
答: 当类中要操作的引用数据类型不确定的时候,早期定义Object 来完成扩展
现在定义泛型来完成扩展
import java.util.ArrayList;
import java.util.Iterator;
public class Test {
public static void main(String[] args) {
//ArrayList al = new ArrayList();
ArrayList<String>al = new ArrayList<>(); //定义一个字符串类型的容器
al.add("abc01");
al.add("abc0251");
al.add("abc014");
//Iterator ie = al.iterator();
Iterator<String> ie = al.iterator();
while(ie.hasNext()) {
//String s = (String)ie.next();
String s = ie.next();
System.out.println(s+":"+s.length());
}
}
}
如果需要new一次对象,需要使用多种数据类型,那就在方法中定义泛型
//特殊之处:
静态方法不可以访问类上定义的泛型。
如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上
class Demo{
public<T> void show(T t){
System.out.println("show"+t);
}
public<E> void show(E e){
System.out.println("show"+e);
}
}
class TestDemo{
public static void main(String[]args){
Dome d =new Demo();
d.show("haha");
d.show(new Integer(5));
}
}
---------------------------------------------------
// 泛型限定高级应用
/**
? 通配符。 也可以理解为占位符。
泛型的限定:
? extends E: 可以接收E类型或者E子类型。 上限
? super E: 可以接收E类型或则E的父类型。 下限
*/
public static void main(String[]args){
ArrayList<Person> al = new ArrayList<>();
al.add(new Person("abc1"));
al.add(new Person("abc2"));
al.add(new Person("abc3"));
printColl(al);
ArrayList<Student> al1 = new ArrayList<>();
al1.add(new Student("abc--1"));
al1.add(new Student("abc--2"));
al1.add(new Student("abc--3"));
printColl(al1);
}
public static void printColl(ArrayList< ? extends Person> al){ //只能定义person的子类型
Iterator< ? extends Person> it = al.iterator(){
while(it.hasNext()){
System.out.println(it.next().getName());
}
}
}
Map
Map集合: 该集合存储键值对,一对一对往里存,而且要保证键的唯一性。
1.添加:
添加元素时如果出现相同的键,那么后添加的值会覆盖原有的键对应的值。 并put方法会返回被覆盖的值
put(k key ,v value) putAll(Map< ? extends k, ? extends v > m)
2.删除:
clear() remove(object key)
3.判断:
containsValue(object value) containsKey(object key) isEmpty()
4.获取:
get(object key) size() value()
entrySet() keySet()
Map三个子类:
|------ Hashtable: 底层时哈希表数据结构,不可以存入null键null值。该集合是线程同步的。jdk1.0 效率低
|------HashMap: 底层是哈希表数据结构,允许使用null值和null键,该集合是不同步线程的。jdk1.2 效率高
|------TreeMap:底层是二叉树数据结构。线程不同步。可以用于给map集合中的键进行排序。
和Set很像。 其实大家Set底层就是使用了Map集合
Map.Entry 其实Entry也是一个接口,他是Map接口中的一个内部接口
interface Map{
public static interface Entry{
public abstreact Object getKey();
public abstreact Object getValue();
}
}
main方法{
Map<String,String> map =new <>();
map.put("02","hua");
map.put("01","hua");
map.put("05","hua");
map.put("04","hua");
//先获取map集合的所有键的Set集合,keySet();
Set<String>keySet = map.keySet();
//有了Set集合,就可以获取其迭代器
Iterator<String> it = keySet.iterator();
while(it.hashNext()){
String key =it.next();
//有了键可以通过map集合的get方法获取其对应的值
String value = map.get(key);
System.out.println("key:"+key+",value:"+value);
}
}
/*练习:
“sdfgzxcvasdfxcvdf” 获取该字符串中的字母出现的次数
希望打印结果是 : a几个 c几个 表明出现的次数
通过结果发现字母和次数之间都有映射关系
注意了,当发现有映射关系时就要想到map集合,因为map集合中存放就是映射关系
思路:
1、将字符串转换成字符数组,因为要对每一个字母进行操作。
2、定义一个map集合,因为打印结果的字母有顺序,所以使用treemap集合。
3、遍历字符数组:
将每一个字母作为键去查map集合。
如果返回null,将该字母和1存入到map集合中。
如果返回不是null,说明该字母在map集合已经存在并有对应次数。
那么就获取该次数并进行自增,然后将该字母和自增后的次数存入到map集合中。覆盖原有的对应值
4、将map集合中的数据变成指定的字符串形式返回 */
import java.util.*;
class MapTest3{
public static void main(String[]args){
charCount("aabfdabccdefdesa");
//String s = charCount("aabfdabccdefdesa");
//System.out.println(s);
}
public static StringcharCount(String str){
chsr[] chs =str.toCharArray();
TreeMap<Character,Integer> tm = new TreeMap<>();
//int count=0;
for(int x = 0; x< chs.length; x++){
Integer value =tm,get(chs[x]);
/* 这个判断比较简便
if(value!=null){
count= value;
count++;
tm.put(chs[x],count);
count =0;
}*/
if(value==null){
tm.put(chs[x],1);
}else{
value = value+1;
tm.put(chs[x],value)
}
}
System.out.println(tm);
/*StringBuilder sb =new StringBuilder();
Set<Map.Entry<Character,Integer>> entrySet =tm.entrySet();
Iterator<Map.Entry<Character,Integer>> it = entrySet.iterator();
while(it.hasNext()){
Map.Entry<Character,Integer> me =it.next();
Character ch =me.getKey();
Integer value =me.getValue();
sb.append(ch+"("+value+")");
}
return sb.toString();*/
return null;
}
}
Runtime对象
Runtime 对象类并没有提供构造函数。
说明不可以new对象。name会直接想到该类中的方法都是静态的。
发现该类中还有非静态方法。
说明该类肯定会提供了方法获取本类对象。而且该方法是静态的,并返回类型是本类类型。
该方式是 static Runtime getRuntime();
class RuntimeDemo{
public static void main(String[]args) throws Exception{
Runtime r = Runtime.getRuntime();
r.exec("c:\\winmine.exe");
/*Process p =r.exec("winmine.exe");
Thread.sleep(4000); 让子线程等4秒在杀掉
p.destroy(); //杀掉子进程*/
}
}
Date 日期类
import java.util.*;
import java.text.*;
class DateDemo{
public static void main(String[]args){
Date d = new Date();
System.out.println(d); //打印的时间看不懂,希望有些格式。
//将模式封装到SimpleDateformat对象中。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 E hh:mm:ss");
//调用format方式让格式化指定Date对象。
String time = sdf.format(d);
System.out.println("time="+time);
}
}
main方法{
Calendar c = Calendar.getInstance();
//c.set(2022,2,13);
c.add(Calendar.YEAR,4); //c.add(Calendar.DAY_OF_MONTH,-18);
printCalendar(c);
}
public static void printCalendar(Calendar c){
String[] mons = {"一月","二月","三月","四月",
"五月","六月","七月","八月","九月",
"十月","十一月","十二月"};
String[] weeks = {"","星期日","星期一","星期二","星期三","星期四","星期五","星期六"};
int index = c.get(Calendar.MONTH);
int index1 = c.get(Calendar.DAY_OF_WEEK);
sop(C.get(Calendar.YEAR)+"年");
//sop((C.get(Calendar.MONTH)+1)+"月");
sop(mons[index]);
sop(c.get(Calendar.DAY_OF_MONTH)+"日");
//sop("星期"+c.get(Calendar.DAY_OF_WEEK));
sop(weeks[index1]);
}
}
public static void sop(Object obj){
System.out.println(obj);
}
System 类应用
import java.util.Properties;
public class SystemDemo {
public static void main(String[] args) {
Properties prop =System.getProperties();
/**
* 因为properties是Hashtable的子类,也就是Map集合的一个子类对象。
* 那么可以通过map的方法取出该类集合中的元素。
* 该集合中存储都是字符串,没有泛型定义
*/
//如何在系统中自定义一些特有信息呢?
System.setProperty("myky","myvalue");
/*
* 获取所有属性的信息
for(Object obj : prop.keySet()) {
String value = (String)prop.get(obj);
System.out.println(obj+"::"+value);
}*/
//获取指定属性信息。
String value =System.getProperty("os.name");
System.out.println("value="+value);
}
}
/*
获取任意年的二月有多少天。
思路: 根据指定年设置一个时间就是
c.set(year,2,1) //某一年的三月一日,从0开始的,所以2就是3月
c.add(Calendar.DAY_OF_MONTH,-1); //3月1日,往前推一天,就是2月最后一天。
*/
Math
Math.round(2.5) 等于多少? 答案: 3
Math.round(-2.5)等于多少? 答案:-2
main方法{
double d = Math.ceil(16.34);//ceil返回大于指定数据的最小整数
double d1= Math.floor(12.35);//floor返回小于指定数据的最大整数。
long l =Math.round(12.54); //四舍五入
sop(d);
sop(d1);
sop(l);
double d2= Math.pow(2,3); //2的3次方 8.0
sop(d2)
}
public static void sop(Object obj){
System.out.println(obj);
}
反射的基石 ----> class类
反射就是把Java类中的各种成分映射成相应的Java类。
如何得到各个字节码对应的实例对象(class类型)
- 类名点class 例如: System.class // 获得这个类的直接码
- 对象点getClass, 例如:new Date().getClass() //
- Class.forName(“类名”), 例如: Class.forName(“java.util.Date”); 做反射用的频率很高-0
public class ReflectTest {
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
String str1 = "abc";
Class cla1 =str1.getClass();
Class cla2 =String.class;
Class cla3 =Class.forName("java.lang.String");
System.out.println(cla1==cla2); //true
System.out.println(cla1==cla3); //true
System.out.println(cla1.isPrimitive());//是基本类型吗 false
System.out.println(int.class.isPrimitive());//true
System.out.println(int.class==Integer.class);//false
System.out.println(int.class==Integer.TYPE);//true
System.out.println(int[].class.isArray());//true
}
}
Constructor类
-
constructor类代表某个类中的一个构造方法
-
得到某个类所有的构造方法:
1. 例子: Constructor[] constructors =Class.forName("java.lang.String").getConstructors();
-
得到某一个构造方法:
例子: Constructor constructor = Class.forName(“java.lang.String”).getConstructor(StringBuffer.class);
- 创建实例对象:
通常方式: String str = new String(new StringBuffer(“abc”));
反射方式: String str = (String)constructor.new Instance(new StringBuffer(“abc”));