为什么nextInt方法不是静态的
今天还是一如往常的在练习双列集合
哈希表集合的三种遍历,键值对应,lambda表达式什么的
import java.util.*;
class student{
private String name;
private int age;
public student() {
}
public student(String name, int age) {
this.name = name;
this.age = age;
}
/**
* 获取
* @return name
*/
public String getName() {
return name;
}
/**
* 设置
* @param name
*/
public void setName(String name) {
this.name = name;
}
/**
* 获取
* @return age
*/
public int getAge() {
return age;
}
/**
* 设置
* @param age
*/
public void setAge(int age) {
this.age = age;
}
@Override
public int hashCode() {
return super.hashCode();
}
@Override
public boolean equals(Object obj) {
return super.equals(obj);
}
public String toString() {
return "student{name = " + name + ", age = " + age + "}";
}
}
public class Main {
public static void main(String[] args) {
student s1=new student("朱道阳",20);
student s2=new student("王多多",21);
Map <student,String>map=new HashMap<>();
map.put(s1,"北华大学");
map.put(s2,"南京交通职业技术学院");
map.forEach((student,string)
-> System.out.println(student+string));
}
}
public class Main {
public static void main(String[] args) {
String str[]={"A","B","C","D"};
ArrayList<String>list=new ArrayList<>();
Random r=new Random();
for (int i = 0; i < 80; i++) {
//System.out.println(str[r.nextInt(str.length)]);
list.add(str[r.nextInt(str.length)]);
}
HashMap<String,Integer> hashMap=new HashMap<>();
for (String place : list) {
if(hashMap.containsKey(place)){
int count=hashMap.get(place);
count++;
hashMap.put(place,count);
}
else {
hashMap.put(place,1);
}
}
hashMap.forEach((string,integer) ->
System.out.println
(string+" "+integer));
int max=0;
Set<Map.Entry<String,Integer>>entries =hashMap.entrySet();
for(Map.Entry<String,Integer>entry :entries){
int count=entry.getValue();
if(count>max)
max=count;
}
System.out.println(max);
for(Map.Entry<String,Integer>entry:entries){
int count=entry.getValue();
if(count==max)
System.out.println(entry.getKey());
}
}
}
然后
这里我发现第二题第六行Random类里面的nextInt方法
就是不能直接用类名调用
静态方法可以用类名直接调用者确实
我特地去看了一下源码
源码是这样的
发现在伪随机数类里面确实是这样子书写的
那么为什么nextInt方法要写成实例方法呢
我查了一下资料我认为有以下几个原因
1.种子的可配置性
为什么叫伪随机数呢
因为这个类生成随机数的方法是允许程序员以计算机时间原点为统一时间。程序员可以自由控制随机数生成序列的开始点
如果他是静态的,那么就不能通过对象指定生成不同种子
静态变量是不能访问实例变量的
2.灵活性
提高了Random类的灵活性,你可以创建多个种子,在开发过程中,通过创建多个Random的实例,让每个数字都能有自己的状态,在后续进行使用的时候他们不会进行互相干扰
可以说是完完全全符合了面向对象的封装原则
通过实例方法操作内部状态,而不是通过静态方法操作全局状态
3.状态控制和更加强大
Random类的工作方式是基于一个内部的状态(种子),每次调用随机数生成方法(如nextInt)时,它都会根据当前的种子计算出一个随机数,并更新这个种子(即改变内部状态),以便下一次调用时能产生不同的随机数。如果nextInt是静态的,那么所有使用这个方法的地方都会共享相同的种子状态,这在多线程环境下会导致问题,并且限制了更灵活的随机数生成策略
由于nextInt是实例方法,所以可以在子类中重写它。这意味着你可以扩展Random类,提供自定义的随机数生成逻辑,而仍然保持与原有Random类相同的接口。如果nextInt是静态的,这种类型的扩展就不可能实现
何时声明静态方法
书写静态方法(static method)通常在以下几种情况下是合适的:
- 实用性函数:当你需要一个实用函数,它不依赖于对象的状态(即,它不使用任何非静态成员变量),那么将这个函数定义为静态方法是合适的。例如,一个数学工具类可能包含一些静态方法来执行数学运算。
- 工厂方法模式:在设计模式中,静态方法经常被用作工厂方法。工厂方法是一种创建对象的方法,而不必指定将要创建的对象的确切类别。这种情况下,静态方法可以根据输入参数的不同返回不同类的实例。
- 辅助方法:如果你有一些方法,它们仅仅是用来辅助类中的其他方法,而且这些方法不需要访问对象的状态,那么将它们定义为静态方法是有意义的。
- 状态无关的方法:如果方法的行为不依赖于对象的状态,即它不修改也不读取对象的非静态字段,那么这个方法应该被声明为静态的。
- 单例模式:在单例模式的实现中,通常会使用一个静态方法来获取这个唯一实例的引用。
- 性能考虑:由于静态方法不需要创建对象就能调用,因此在某些需要频繁调用的场景下,使用静态方法可能会略微提升性能。但这种性能优化通常很小,仅在极端性能敏感的应用中才需要考虑。
注意事项
- 使用静态方法时,需要注意不能滥用。静态方法不能访问类的非静态成员变量或方法,这在某种程度上限制了它们的使用场景。
- 静态方法不能被覆盖,因为它们不是通过对象实例调用的,而是通过类名调用的。这意味着静态方法的行为不会通过继承来改变。
- 过多地使用静态方法可能会导致面向过程的编程风格,而不是面向对象的编程风格,这可能会降低代码的可读性和可维护性。
在使用静态方法时,应当仔细考虑它们是否真的适合当前的设计需求。