念觉

jys


  • 首页

  • 关于

  • 标签

  • 归档

  • 留言板

反射/代理

发表于 2020-10-08 |

反射

反射详解

1
2
3
4
5
6
7
8
9
10
* 常用相关api:
* java.long.Class: 代表一个类 ---test3()
* 1.类的加载过程: 程序执行javac.exe命令以后,会生成一个或多个字节码文件(.class文件)。
* 接着使用java.exe命令对某个字节码文件进行解释运行,相当于某个字节码文件加载到内存中。此过程就称为
* 类的加载。加载到内存中的类,我i们成为运行时类,此运行时类,就作为一个Class的一个实列
* 2.Class实例也就是一个运行时类
* 3.加载到内存的运行时类,会缓存一段时间,在此时间内我们可以通过不同的方式来获取此运行时类
* java.long.reflet.Method: 代表类的方法
* java.long.reflet.Field: 代表类的成员变量
* java.long.reflet.Constructor:代表类的构造器

疑问:

  什么时候用反射?
  编译时期确定不了用哪个类的对象 (servlet 中的体现,根据前端请求确认用户执行那些操作(例如:登陆,注册)创建相关对象)

创建类的对象的几种方式:

  1)new +构造器

  2)类本身或工具类提供的静态方法创建对象

  3)反射

获取Class实例的几种方式
方式一:调用运行时类的属性
1
2
Class<Person> class1 = Person.class;
System.out.println(class1); //输出Person类本身---->class cn.itcast.base.Person
方式二:通过运行时对象
1
2
3
Person p1=new Person();
Class class2 = p1.getClass();
System.out.println(class2); //class cn.itcast.base.Person
方式三:调用Class的静态方法 (推荐)
1
2
3
4
5
6
Class class3 = Class.forName("cn.itcast.base.Person");//类的全类名
System.out.println(class3); //class cn.itcast.base.Person

//比较发现运行时类是同一个
System.out.println(class1 == class2); //true
System.out.println(class1 == class3); //true
方式四 调用类的加载器加载ClassLoader (了解)
1
2
3
4
5
6
7
ClassLoader classLoader = ReflexTest.class.getClassLoader();
try {
Class class4 = classLoader.loadClass("cn.itcast.base.Person");
System.out.println(class4); ////class cn.itcast.base.Person
} catch (ClassNotFoundException e) {
e.printStackTrace();
}

反射操作

Person基类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
public class Person {
private String name;
public int age;
public Person(){

}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
private Person(String name){
this.name=name;
}
public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}

private void hello(){
System.out.println("private void");
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

Person person = (Person) o;

if (age != person.age) return false;
return name != null ? name.equals(person.name) : person.name == null;
}

@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}

@Override
public String toString() {
return "Persion{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}

}

通过反射Person的操作:

1)通过反射创建Person对象
1
2
3
4
Class<Person> personClass = Person.class;
Constructor<Person> constructor = personClass.getConstructor(String.class, int.class);
Person person = constructor.newInstance("antusheng", 18);
System.out.println(person.toString()); //Persion{name='antusheng', age=18}
2)通过反射调用对象指定的方法,属性
1
2
3
4
5
6
7
8
Field age = personClass.getDeclaredField("age");
age.set(person,21);
System.out.println(person.toString()); //Persion{name='antusheng', age=21}
//调用方法
Method setName = personClass.getDeclaredMethod("setName", String.class);
//如果调用的方法没有返回值,此invoke返回null
setName.invoke(person,"安徒生");
System.out.println(person.toString()); //Persion{name='安徒生', age=21}
3)调用私有构造器
1
2
3
4
Constructor<Person> cons1 = personClass.getDeclaredConstructor(String.class);
cons1.setAccessible(true);
Person p1=cons1.newInstance("Tom");
System.out.println(p1); //Persion{name='Tom', age=0}
4)调用私有属性
1
2
3
4
5
Field name = personClass.getDeclaredField("name");
//属性是private的,设置为true保证属性可访问
name.setAccessible(true);
name.set(p1,"安徒生jy");
System.out.println(p1); //Persion{name='安徒生jy', age=0}
5)调用私有方法
1
2
3
Method hello = personClass.getDeclaredMethod("hello");
hello.setAccessible(true);
hello.invoke(p1); //private void

代理

  代理设计模式原理: 使用一个代理将对象包装起来,然后该代理类对象取代原始对象。任何对原始对象的调用都要通过代理。代理对象决定是否以及何时将方法调用到原始对象

静态代理

代理类和被代理类在编译期间都确定下来。

接口定义:

1
2
3
interface ClohtFactory{
void produceCloth();
}

定义代理类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class  ProxyClothFactory implements ClohtFactory{
private ClohtFactory factory; //用被代理对象进行实例化
public ProxyClothFactory(ClohtFactory clohtFactory){
this.factory=clohtFactory;
};
@Override
public void produceCloth() {
System.out.println("代理工厂准备一些准备工作");

factory.produceCloth();

System.out.println("代理工厂做后续的一些工作");
}
}

被代理类:

1
2
3
4
5
6
7
class NikeClothFactory implements ClohtFactory {

@Override
public void produceCloth() {
System.out.println("Nike工厂生产一批新款运动服装");
}
}

进行静态代理测试:

1
2
3
4
5
6
7
8
9
10
11
12
public class StaticProxyTest  {
public static void main(String[] args) {
//创建代理类对象
NikeClothFactory nike=new NikeClothFactory();
//创建被代理类对象
ProxyClothFactory proxyClothF=new ProxyClothFactory(nike);
proxyClothF.produceCloth();
//代理工厂准备一些准备工作
//Nike工厂生产一批新款运动服装
//代理工厂做后续的一些工作
}
}

动态代理

在程序运行时确定代理对象,通过反射获得运行时类创建代理类。

接口定义:

1
2
3
4
interface Human{
String getBelief();
void ear(String food);
}

被代理类:

1
2
3
4
5
6
7
8
9
10
11
12
class SuperMan implements  Human{

@Override
public String getBelief() {
return "我相信自己";
}

@Override
public void ear(String food) {
System.out.println("我喜欢吃"+food);
}
}

实现动态代理需要解决问题:

1)如何根据加载到内存中的被代理类,动态的创建一个代理类及其对象?
2)当通过代理类的对象调用方法时,如何动态的取调用被代理类的同名方法?

1
2
3
4
5
6
7
8
9
class ProxyFactory{
//调用此方法。返回一个代理类对象,解决问题一
public static Object getProxyInstance(Object obj){
MyInvocationHandler myHandler = new MyInvocationHandler();
myHandler.bind(obj);
return Proxy.newProxyInstance(obj.getClass().getClassLoader(),obj.getClass().getInterfaces(),myHandler);
}//通过Proxy类的静态方法newProxyInstance返回一个接口的代理实例。针对不同的代理类,传入相应的代理程序控制器InvocationHandler

}

构建 MyInvocationHandler实现InvocationHandler接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class MyInvocationHandler implements InvocationHandler{
private Object object; //需要使用被代理类对象进行赋值

public void bind(Object object){
this.object=object;
}

//当通过代理类的对象调用某个方法x时,就会自动调用如下的方法:invoke()方法
//将被代理类要执行的方法x要执行的功能声明在invoke中
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

//代理类对象调用的方法,此方法也作为被代理类对象调用的方法
//object 本身就是被代理对象
Object returnInvoke = method.invoke(object, args);
//上述方法的返回值就作为当前类的invoke()方法的返回值
return returnInvoke;
}
}

动态代理测试:

1
2
3
4
5
6
7
8
9
10
11
public static void main(String[] args) {
SuperMan superMan = new SuperMan();
//Object proxyInstance = ProxyFactory.getProxyInstance(superMan);
Human proxyInstance = (Human) ProxyFactory.getProxyInstance(superMan);
String belief = proxyInstance.getBelief();
System.out.println(belief);
proxyInstance.ear("烤肉");
/*我相信自己
我喜欢吃烤肉*/

}

Java中常用集合分类及其常用方法

发表于 2020-09-30 |

Collection

Collection 继承图

List(有序,可重复)

ArrayList

​ ArrayList集合(详细转向Array/ArrarList 常用方法)

​ 特点:

​ 1.数字长度可以任意变化

​ 2.代表泛型,泛型也就是装在集合中的所有元素,全部都是统一的某种类型

​ 注意:泛型只能是引用类型不能是基本类型

​ 3.对于ArrayList来说直接打印的得到的不是地址值而是内容,如果内容为空则打印[]

​ ArrayList 底层是数据存储结构是数组,元素增删慢,查询快;

LinkedList

​ java.util.LinkList 集合 implements List
​ LinkList 集合 存储的结构是链表结构,查询慢,增删快
​ 包含大量操作首尾元素方法:
​ public void addFirst(E e):将指定元素插入此列表的开头
​ public void addLast(E e):将指定元素插入此列表的结尾
​ public void push(E e):将此元素推入此列表表示的堆栈

​ public E getFirst():返回列表的第一个元素
​ public E getLast():返回列表的最后一个元素

​ public E removeFirst(E e):移除列表的第一个元素,并返回该元素
​ public E removeLast(E e):移除列表的最后一个元素,并返回该元素
​ public E pop():从此列表表示的堆栈处返回一个元素

​ public boolean isEmpty(): 如果此列表为空返回true

​

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
LinkedList<String> linkedList=new LinkedList<>();
linkedList.addFirst("a"); //将指定元素插入此列表的开头
linkedList.addLast("d"); //将指定元素插入此列表的结尾
linkedList.push("c"); //等效于addFirst
System.out.println(linkedList); //[c,a,d] 并不是地址值,重写了toString方法
String str1=linkedList.getFirst(); //返回列表的第一个元素
System.out.println(str1); //c
String str2=linkedList.getLast(); //返回列表的最后一个元素
System.out.println(str2); //d

String str3=linkedList.removeFirst(); //移除列表的第一个元素,并返回该元素
System.out.println(str3); //c
String str4=linkedList.removeLast(); //移除列表的最后一个元素,并返回该元素
System.out.println(str4); //d
String str5=linkedList.pop(); //从此列表表示的堆栈处返回一个元素,本质出栈(移除)是第一个
System.out.println(str5); //a
System.out.println(linkedList.isEmpty()); //true

​

Set(无序,唯一)

java.util.Set extends Collection
Set接口的特点:
1.不允许重复元素
2.没有索引,没有带索引的方法,不能用for循环

HashSet

java.util.HashSet extends Set
特点:
包含set特点
1.是一个无序元素集合,存储元素和取出元素的顺序可能不一致
2.底层是一个哈希结构表(存取速度快)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
Set<Integer> hashSet = new HashSet<>();
//通过add添加元素
hashSet.add(54);
hashSet.add(45);
hashSet.add(88);
//通过迭代器遍历set集合元素
Iterator<Integer> iterator = hashSet.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());// 54 45 88
}
//增强for遍历set集合(底层还是迭代器)
for (Integer integer : hashSet) {
System.out.println(integer); // 54 45 88
}

HashCode

哈希值:是一个十进制的整数,由系统随机给出。(就是对象的地址值,是一个逻辑地址,是模拟出来得到地址,不是实际的物理地址)
在Object类有一个方法可以获得对象的哈希值
int hashCode(); 返回对象的哈希值码
HashCode方法的源码:
public native int hashCode();
native 代表该方法调用的是本地操作系统的方法
Object的toString()输出的也是哈希值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
bject object=new Object();
System.out.println(object.hashCode());//22307196

//String类重写了hashCode() 方法
String s1="abc";
String s2="abc";
System.out.println(s1.hashCode()); //96354
System.out.println(s2.hashCode()); //96354
System.out.println("重地".hashCode()); //1179395
System.out.println("通话".hashCode()); ////1179395

//HashSet使用HashCode对比元素,不允许重复
HashSet<String> hashSet=new HashSet();
hashSet.add(s1);
hashSet.add(s2);
hashSet.add("通话");
hashSet.add("重地");
System.out.println(hashSet); //[通话, 重地, abc]

//HashSet 存储自定义类型 要求重写equals()和hashCOde() 方法
HashSet<Persion> hashSet1=new HashSet();
Persion p1=new Persion("安徒生",20);
Persion p2=new Persion("安徒生",20);
Persion p3=new Persion("安徒生",22);
hashSet1.add(p1);
hashSet1.add(p2);
hashSet1.add(p3);
System.out.println(hashSet1);
//[Persion{name='安徒生', age=20},Persion{name='安徒生', age=22}, Persion{name='安徒生', age=20}]
//没有重写equals() 和 hashcode()方法
System.out.println(p1.hashCode()); //10568834
System.out.println(p2.hashCode()); //21029277
System.out.println(p3.hashCode()); //24324022
System.out.println(p1.equals(p2)); //false
//在Persion类中重写equals和hashCode方法后
System.out.println(p1.equals(p2)); //true
System.out.println(p1.hashCode()); //722533822
System.out.println(p2.hashCode()); //722533822
System.out.println(p3.hashCode()); //722533824
System.out.println(hashSet1); //[Persion{name='安徒生', age=22}, Persion{name='安徒生', age=20}]


//persion 类
public class Persion {
private String name;
private int age;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

Persion persion = (Persion) o;

if (age != persion.age) return false;
return name != null ? name.equals(persion.name) : persion.name == null;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + age;
return result;
}
@Override
public String toString() {
return "Persion{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public Persion(){
}
public Persion(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}

LinkedHashSet

java.util.linkedHashSet 集合 extend HashSet集合

LinkedHashSet: 底层是一个哈希表(数组+链表/红黑树)+链表:多了一条链表(记录元素的存储顺序),保证元素有序。

1
2
3
4
5
6
HashSet<String> linkedSet=new LinkedHashSet<>();
linkedSet.add("www");
linkedSet.add("iiswho");
linkedSet.add("www"); //重复添加www
linkedSet.add("com");
System.out.println(linkedSet);//[www, iiswho, com] 有序不允许重复 HashSet是无序的不循序重复

Map(键值对)

Map集合特点

java.util.map<k,v>集合
​ 1.Map集合中元素是一个双列集合,一个元素可以包含两个值(一个key,一个值);
​ 2.Map集合中的元素,key和value的数据类型可以相同,亦可以不同
​ 3.Map集合中的元素,key是不允许重复的,value是允许重复的
​ 4.Map集合中,key和value是一一对应的

HashMap集合的特点:

java.util.HashMap<k,v>集合 implements Map<k,v> 接口
​ 1.HashMap集合的底层是哈希表:查询速度快
​ jdk1.8之前:数组+单向链表
​ jdk1.8之前:数组+单向链表/红黑树(链表的长度超过8);提高查询速度
​ 2.HashMap集合是一个无序的集合,存储元素和取出元素的顺序有可能不一致

LinkedHashMap特点:

java.util.linkedHashMap<k,v> extends HashMap<k,v> 集合
​ 1.linkedHashMap底层是哈希表+链表
​ 2.linkedHashMap集合是一个有序集合,存储元素和取出元素是一致的

Map集合常用方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
/*
* public V put(K key,V value) -将指定的键和指定的值添加到map集合中
* 当存储键值对时,key不重复返回V时null,key重复时,会使用新的value替换重复的value值,返回被替换的value
* */
Map<String,String> map=new HashMap();
String str=map.put("1","hello");
System.out.println(str); //null
str=map.put("1","world");
System.out.println(str); //hello
str=map.put("2","!!!");
System.out.println(map); //{1=world, 2=!!!}
/*
* public V remove(object key)
* 把指定的键对应的键值对元素在map集合中删除,返回被删除的元素,key存在V返回被删除的值,不存在返回null
* */
str=map.remove("!!!");
System.out.println(str); //null
str=map.remove("2");
System.out.println(str); //!!!
/*
* public V get(K key): 根据指定值键在map集合中获取对应的值
* key存在返回对应的的值,不存在返回nul
* */
str=map.get("1");
System.out.println(str); //world
//public boolean containsKey(Object key) 判断集合中是否包含指定的键
System.out.println(map.containsKey("1"));//true

/*
* 遍历Map集合 将Map集合中的Key取出放到Set集合中,使用迭代器遍历Set集合获取每一个key对应的值
* */
map.put("遍历","set");
map.put("键","值");
//keySet() 将Map集合中的Key取出放到Set集合中
Set set=map.keySet();
Iterator<String> iterator=set.iterator();
while (iterator.hasNext()){
String key=iterator.next();
System.out.println(key+":"+map.get(key));//1:world 遍历:set 键:值
}

String类常用方法

发表于 2020-09-24 |

String类常用方法

java.long.String 包
特点:
1.程序中任何“ ”字符串都是String类的实列对象
2.字符串不变; 它们的值在创建后不能被更改。
3.字符串缓冲区支持可变字符串因,为String对象是不可变的,它们可以被共享。
4.字符串效果上时char[]字符数组,但底层原理时byte[]字节数组
常见创建字符串的3+1种类方式:
三种构造方法:
public String(); 创建一个空白字符串
public String(char[] String ); 根据字符数组中的内容,来创建对应的字符串
public String(byte[] String); 根据字节数组中的内容,来创建对应的字符串
一种直接创建:
String str=”Hello”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//空参构造
String str1=new String();
System.out.println(str1);
//字符数组构造
char[] charArray=new char[]{'H','E','L','L','O'};
String str2=new String(charArray);
System.out.println(str2);
//字节数组构造
byte[] byteArray={'W','O','R','L','D'};
String str3=new String(byteArray);
System.out.println(str3);
//直接创建
String str4="I";
System.out.println(str4);
字符串常量池:程序中直接写上双引号的字符串,就在字符串常量池中. 对于基本类型来说,==是进行数值的比较 对于引用类型来说,==是进行【地址值】的比较
1
2
3
4
5
6
7
String str1 ="abc";
String str2 ="abc";
char[] charArray={'a','b','c'};
String str3=new String(charArray);
System.out.println(str1==str2); //true
System.out.println(str1==str3); //false
System.out.println(str2==str3); //false

程序运行图

字符串内容比较:
public boolean equals(Object obj);参数可以是任何对象,只有一个参数是一个字符串并且内容相同
才会给true 否则返回false。
注意:
1.equals方法具有对称性,a.equals(b)和b.equals(a)效果一样
2.如果比较双方一个常量一个变量,推荐把常量放在前 “abc”.equals(str),否则容易空指针异样
public boolean equalsIgnoreCase(Object obj); 忽略大小写,进行内容比较

1
2
3
4
5
6
7
8
9
10
11
12
String str1 ="abc";
String str2 ="abc";
char[] charArray={'a','b','c'};
String str3=new String(charArray);
System.out.println(str1.equals(str2)); //true
System.out.println(str1.equals(str3)); //true
System.out.println(str2.equals(str3)); //true
System.out.println("abc".equals(str2)); //true
//equalsIgnoreCase
String str4 ="ABC";
System.out.println(str4.equals(str2)); //fasle,区分大小写
System.out.println(str4.equalsIgnoreCase(str2)); //true,忽略大小写
String 中常用的方法:

​ public int length(); 获取当前字符串中的字符个数,拿到字符串长度
​ public String concat(String str); 将当前字符串和参数字符串拼接为新的字符串返回
​ public char charAt(int index); 获取指定索引位置的字符(索引从0开始)
​ public int indexOf(String str); 查找指定字符串在本字符串首次出现的索引位置,没有返回-1值

截取字符串:

​ public String substring(int index);截取从参数位置一直到字符串末尾,返回新字符串
​ public String substring(int begin,int end);截取从begin开始,直到end结束,中间的字符串。
​ [begin,end)此方法是左闭右开区间

转换字符串:

​ public char[] tocharArray();将当前字符串拆分成为字符数组作为返回值
​ public byte[] getBytes(); 获得当前字符串底层的字节数组.
​ public String replace(CharSequence oldString,CharSequence new String);
​ 将所有出现的老字符串替换为新的字符串,返回替换之后的新字符串,
​ CharSequence 值可以接收字符串类型

切割字符串:

​ public String[] split(String regex);按照指定规则将字符串分割为若干部分
​ 注意: splir方法的参数其实是一个”正则表达式”,如果按照英文”.”进行切分,必须写”\“ =>”\.”

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
String str1="Hello";
String str2="World";
//获取字符串长度
System.out.println("str1字符串长度是:"+str1.length());
//拼接字符串
System.out.println(str1); //Hello
System.out.println(str2); //World
System.out.println(str1.concat(str2)); //HelloWorld
//获取指定索引位置
System.out.println(str1.charAt(1)); //e
//查找指定位置字符串
System.out.println(str2.indexOf("r")); //2
//截取字符串
System.out.println(str1.substring(1)); //ello
System.out.println(str1.substring(1,3)); //el
//转换为字符数组
char[] chars="Hello".toCharArray();
System.out.println(chars[0]); //H
System.out.println(chars.length); //5
//转换为字节数组
byte[] bytes = "abc".getBytes();
for (int i = 0; i < bytes.length; i++) {
System.out.println(bytes[i]); // 97 98 99
}
//字符串替换
String string="i am china";
System.out.println(string.replace("am","love"));// i love china
//分割字符串
String str5="abc,def,ghl";
String[] strings=str5.split(",");
for (int i = 0; i < strings.length; i++) { //abc def ghl
System.out.println(strings[i]);
}

Array/ArrarList 常用方法

发表于 2020-09-23 |

Array / ArrayList 基本使用

注意程序运行时堆,栈,方法区的变化:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
* Java的内存划分为5个部分:
* 1.栈(Stack):存放的都是方法中的局部变量
* 局部变量:方法的参数或者是方法{}中的变量
* 作用域: 一旦超出作用域,立刻从栈中消失
* 2.堆(Heap):凡是new出的东西都在堆当中
* 堆内存中的东西都有一个地址值:16进制
* 堆内存中的数据默认都有值。规则:
* 整数 默认:0
* 浮点数 默认:0.0
* 字符 默认:'\u0000'
* 布尔 默认:false
* 引用类型 默认:null
*
* 3.方法区(Method Area): 存储class相关信息。包含方法的信息
* 4.本地方法栈(Native Method Stack):与操作系统相关
* 5.寄存器(pc Register): 与cpu相关

补充:

1
2
3
4
5
java四类八种基本数据类型 度量单位均为字节
第一类:整型 byte 1 short 2 int4 long8
第二类:浮点型 float4 double8
第三类:逻辑型 boolean(它只有两个值可取true false) 1/8字节
第四类:字符型 char

Array基本用法

数组是一组容器,用来存放多个数据值
特点:

1.数组是一种引用数据类型

2.数组中的多个数据类型类型必须统一

3.数组的长度在程序运行期间不能改变

两种初始化方式:
1)动态初始化 数据类型[] 数组名称=new 数据类型[组数长度]
2)静态初始化 数据类型 数组名称=new 数据类型{元素1,元素2,….};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
//定义声明
String[] str=new String[5];
int[] array=new int[]{5,15,35,6,78,66};
byte[] bytes={'1','5','6'};

//获取最大值
public int getMax(int[] arr){
int max=0;
for(int i=1; i<arr.length;i++){
if(arr[i]>arr[max]){
max=i;
}
}
return arr[max];
}

//获取最小值
public int getMin(int[] arr){
int min=0;
for(int i=1; i<arr.length;i++){
if(arr[i]<arr[min]){
min=i;
}
}
return arr[min];
}

//排序
public void selectBort(int[] arr){
for(int x=0;x<arr.length;x++){
for(int y=x+1;y<arr.length;y++){
if(arr[x]>arr[y]){
swap(arr,x,y);
}
}
}
}

public void swap(int[] arr,int a,int b){
int temp=arr[a];
arr[a]=arr[b];
arr[b]=temp;
}

/**
* 稀疏数组
*/
int[][] arr=new int[10][10];
arr[2][3]=10;
arr[5][7]=35;
arr[6][2]=12;
//输出稀疏数组
System.out.println("输出原始数组:");
for (int[] i:arr) {
for (int j:i) {
System.out.printf(j+"\t");
}
System.out.println("");
}

//压缩为稀疏数组
int sum=0;
for (int i = 0; i <arr.length ; i++) {
for (int j = 0; j <10 ; j++) {
if (arr[i][j]!=0){
sum=sum+1;
}
}
}
System.out.println("共有"+sum+"个有效值.");
//进行数组压缩
int [][] arr2=new int[sum+1][3];
arr2[0][0]=10;
arr2[0][1]=10;
arr2[0][2]=sum;
int count=0;
for (int i = 0; i <arr.length ; i++) {
for (int j = 0; j<arr[i].length ; j++) {
if (arr[i][j]!=0){
arr2[count+1][0]=i;
arr2[count+1][1]=j;
arr2[count+1][2]=arr[i][j];
count++;
}
}
}
System.out.println("输出稀疏数组:");
for (int i = 0; i <arr2.length ; i++) {
System.out.println(Arrays.toString(arr2[i]));
}
//将稀疏数组转化为数组输出
System.out.println("将稀疏数组转化为数组:");
int[][] arr3=new int[arr2[0][0]][arr2[0][1]];
for (int i = 1; i <arr2.length ; i++) {
arr3[arr2[i][0]][arr2[i][1]]=arr2[i][2];
}
for (int i = 0; i <arr3.length ; i++) {
for (int j = 0; j <arr3[i].length ; j++) {
System.out.print(arr3[i][j]+"\t");
}
System.out.println(" ");
}

Scanner 键盘输入

注意next与nextLine
next方法不能包含空格,遇见空格认为结束。会一直等待用户输入字符,自动去掉用户输入字符之前的空格
nextLine方法以enter作为结束标志,可以获得空格

1
2
3
Scanner scanner=new Scanner(System.in);
System.out.printf(scanner.next());
scanner.close();

ArrayList基本用法

1.数字长度可以任意变化
2.代表泛型,泛型也就是装在集合中的所有元素,全部都是统一的某种类型
注意:泛型只能是引用类型不能是基本类型
3.对于ArrayList来说直接打印的得到的不是地址值而是内容,如果内容为空则打印[]
4.ArrayList 底层是数据存储结构是数组,元素增删慢,查询快;

1
2
3
4
ArrayList<String> arrayList=new ArrayList();
System.out.print(arrayList);
arrayList.add("hello world");
System.out.print(arrayList);

常用方法:

1.public boolean add ;向集合中添加元素,参数类型和泛型保持一致
备注:对于array List元素来说,add添加元素是一定成功的,返回值可以不用, 其他集合的的add添加动作不一定成功.
2.public E get(int index) ;从集合中获取元素,参数是索引编号,返回值就是对应位置的元素
3.public E remove(int index) ; 从集合中删除元素,参数是索引编号,返回值就是被删除掉的元素
4.public int size() ; 获取集合尺寸长度,返回值是集合中包含的元素个数

1
2
3
4
5
6
7
8
9
10
11
12
boolean success=arrayList.add("I am student");
System.out.print("添加的动作是否成功"+success);
//从集合中获取元素:get.索引值从0开始.
String string=arrayList.get(0);
System.out.printf("从集合中获取的元素是:"+string);
//从集合中删除元素:remove.
String string2=arrayList.remove(0);
System.out.printf("从集合中删除的元素是:"+string2);
//遍历集合
for (int i = 0; i < arrayList.size(); i++) {
System.out.println(arrayList.get(i));
}

ArrayList集合中若想存放基本数据类型,必须使用基本类型对应的包装类基本类型 包装类(引用类型,都位于java.long包下)
byte ==> Byte
int ==> Integer
short ==> Short
long ==> Long
double ==> Double
float ==> Float
char ==> Character
boolean ==> Boolean

1
2
3
4
5
//int 应用类型举例
ArrayList<Integer> listInt=new ArrayList<>();
listInt.add(100);
listInt.add(300);
System.out.println(listInt.get(0));

Markdown

发表于 2020-09-22 |

markdown 常用小技巧

1.通过 #号+空格 表示标题 1-6级(几级标题几个#号)

iiswho.cn

IISWHO.CN

iiswho.cn

iiswho.cn

2.更改字体,大小,颜色

​ 1)粗体 : **iiswho.cn**

​ iiswho.cn

​ 2)斜体: *iiswho.cn*

​ iiswho.cn

​ 3) >+空格 引用效果

此文章来源于iiswho.cn

​ 4)分割线”- - -“或者”***”


​ 5)居中显示

1
<center>居中的内容</center>
居中设置大小<center><font size=4>设置居中内容的大小</font></center>   

​ 6)换行 :使用br标签 或者末尾敲两个空格然后回车

​ 7)精确设置字体

1
<font face="黑体" color=blue size=5>我是黑体,蓝色,尺寸为5</font>
我是黑体,蓝色,尺寸为5

4.图片
![图片名称] (图片地址/本地网络均可) 注意:如若想设置如片大小可添加div容器进行设置

我的头像

5.超链接
[链接标题] (链接地址)
​ 我的博客

6.列表

​ 1)有序: 1.空格

​ 2)无序: ‘-‘+空格

7.代码

1
2
​```+编写语言:
This is java

8.空格(一个汉字两耳光字符/空格)

1)一个空格大小的表示:&ensp+;或&#8194+;。

2)&emsp+;使用2个即可缩进2个汉字。

3)不换行空格:&nbsp+;或&#160+;

idea test

发表于 2019-12-03 |

更新提示

1
2
3
4
5
6
7
8
hexo new "postName"  #新建文章
hexo new page "pageName" # 新建页面
hexo generate # 生成静态页面至public目录
hexo server # 启动服务器(默认端口4000,'ctrl+c'关闭server)
hexo deploy # 项目部署
hexo help # 查看帮助
hexo version # 查看Hexo的版本
hexo clean # 清除Hexo的缓存

###上边的一些命令可以使用简写

1
2
3
4
hexo n
hexo g
hexo d
hexo s

本地调试三连

1
2
3
hexo clean
hexo g
hexo s --debug

###远程部署三连

1
2
3
hexo clean
hexo g
hexo d

Centos7配置Jdk1.8及搭建Tomcat服务

发表于 2018-06-03 |

一. Java JDK1.8配置(Coentos 7)

准备工作

下载 FileZilla(官网的绿色版完全免费)
下载 jdk1.8安装包 tar.gz(Linux下压缩格式)
利用 FileZilla文件传输软件将下载好的压缩包传送到服务器

云服务器端配置(xxx均为自己的文件名)

1.在usr/local/目录下 建立 services/jdk8 目录.
2.解压文件在jdk目录下 使用命令:

1
tar -zvxf xxx.tar.gz

3.解压完成后java 命令可以使用 javac 需要配置环境变量

1
2
3
4
5
vi /etc/profile
在文件最后加入
export JAVA_HOME=/usr/local/services/jdk8(jdk的绝对路径)
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin

到此 javac 测试 没问题就是配置成功

二.在centos7 中安装tomcat

准备工作

下载 tomcat安装包 tar.gz

利用 FileZilla 将下载好的压缩包传送到服务器

云服务器端配置

1.服务器端 在home目录下新建tomcat目录
2.解压文件在tomcat目录下

1
tar -zvxf xxx.tar.gz

3.在解压好的apache-tomcat目录下的bin目录启动服务

1
sh home/tomcat/apache-tomcat/bin/startup.sh

4.这是侯8080端口应该是启动的。使用命令查看

1
netstat -lntup | grep "8080"

5.这时候通过http://服务公网ip地址:8080 可以访问到的。
如果还是访问查看防火墙是否关闭,服务器入站规则是否将8080端口加入。
入站规则配置可以查看相关服务器的官方帮助文档。

阿里云

腾讯云

防火墙相关命令

1.防火墙开/关:

1
2
systemctl stop firewalld
systemctl start firewalld

2.查看防火墙状态

1
systemctl status firewalld

3.开放8080端口

1
2
firewall-cmd --zone=public --add-port=80/tcp --permanent
public 作用范围 port 开放端口号 permanent永久生效(不设定此参数重启失效)

4.查看所有开放端口

1
firewall-cmd --zone=public --list-ports

测试第一篇

发表于 2018-05-27 |
这是搭建好hexo后的第一篇文章

下面做个代码测试

1
2
3
public void main(String[] agrs){
System.out.println("hellw world");
}

标题

本次测试到此结束
安徒生

安徒生

童话里的猪会飞

8 日志
3 标签
RSS
GitHub E-Mail
© 2020 安徒生
私人领域
|
—