一、安装java
1.安装JDK-11
地址:https://jdk.java.net/java-se-ri/11
环境变量配置:(参考:https://blog.csdn.net/weixin_50093343/article/details/109442668)
在终端输入:sudo gedit /etc/profile 以打开配置文件
在终端中添加:
export JAVA_HOME=/usr/local/bin/jdk-11
export CLASSPATH=.:${JAVA_HOME}/lib
export PATH=.:${JAVA_HOME}/bin:$PATH
然后执行 source /etc/profile 使得刚才的配置生效。
通过 java -version 检查是否成功安装。
2.安装eclipse
地址:https://www.eclipse.org/downloads
解压后直接运行 eclipse-inst 就能进入安装界面。
我选了EE,并把 workspace 放在了目录 /usr/local/lib/eclipse-workspace 下。
二、简单使用
1.Hello World
借助 eclipse 的欢迎教程写了一个 Hello World 程序。
先新建一个 Java 项目,再新建一个类。新建类的时候可以勾选自动生成 main() 方法。然后写一个输出 Hello World 就行了。
新建的这个类放在了 default package 下,运行时会报错说没有 package .但因为是默认 package ,所以不论把 package 叫成什么都不对。一种解决方法是建一个自己的包。https://zhidao.baidu.com/question/562423492212681204.html
2.验证数独答案
package mypackage;
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n=in.nextInt();
int m=n*n;
int a[][];
a=new int[m+5][];
for(int i=1;i<=m;i++)
{
a[i]=new int[m+5];
for(int j=1;j<=m;j++)
a[i][j]=in.nextInt();
}
boolean vis[]=new boolean[m+5];
for(int i=1;i<=m;i++)
{
for(int j=1;j<=m;j++)
vis[j]=false;
for(int j=1;j<=m;j++)
{
if(vis[a[i][j]])
{
System.out.println("no");
return;
}
vis[a[i][j]]=true;
}
}
for(int j=1;j<=m;j++)
{
for(int i=1;i<=m;i++)
vis[i]=false;
for(int i=1;i<=m;i++)
{
if(vis[a[i][j]])
{
System.out.println("no");
return;
}
vis[a[i][j]]=true;
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
for(int k=1;k<=m;k++)
vis[k]=false;
for(int i2=(i-1)*n+1;i2<=i*n;i2++)
for(int j2=(j-1)*n+1;j2<=j*n;j2++)
{
if(vis[a[i2][j2]])
{
System.out.println("no");
return;
}
vis[a[i2][j2]]=true;
}
}
System.out.println("yes");
}
}
3.最大连续子段和
package mypackage;
import java.util.*;
import java.math.*;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
BigDecimal bd=new BigDecimal("1e8");
int INF=bd.intValue();
int n=in.nextInt();
int a[]=new int[n+5];
for(int i=1;i<=n;i++)
a[i]=in.nextInt();
int ans=-INF;
for(int i=1,mn=INF;i<=n;i++)
{
a[i]+=a[i-1];
ans=Math.max(ans,a[i]-mn);
mn=Math.min(mn,a[i]);
}
System.out.print(ans);
}
}
三、一些记录
1.长度为0的数组、类似foreach的写法、、利用匿名数组对数组初始化、Arrays.copyOf( )、Arrays.toString( )、Arrays.deepToString( )
对二维数组使用 foreach 的方法如下。
Arrays.copyOf( ) 的第二个参数是新数组的长度。如果 copy 的是一个二维数组,新数组第一维设为该长度,第二维与原数组大小相同。
package tmp;
import java.util.Arrays;
public class Tmp {
public static void main(String[] args) {
int[][] a=new int[10][];
for(int i=1;i<=10;i++)
{
a[i-1]=new int[10];
for(int j=1;j<=10;j++)
{
a[i-1][j-1]=i*1000+j;
}
}
int[] b=new int[0];
int[][] c=Arrays.copyOf(a,2);
for(int[] i:c)
{
for(int j:i)
System.out.printf("c=%d ",j);
System.out.println();
}
b=new int[] {1,2,3,4,5,6,7,8,9,10};
System.out.println(Arrays.toString(b));
System.out.println(Arrays.toString(a));
System.out.println(Arrays.toString(a[0]));
System.out.println(Arrays.deepToString(c));
}
}
输出结果:
c=1001 c=1002 c=1003 c=1004 c=1005 c=1006 c=1007 c=1008 c=1009 c=1010
c=2001 c=2002 c=2003 c=2004 c=2005 c=2006 c=2007 c=2008 c=2009 c=2010
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[[I@6956de9, [I@769c9116, [I@6aceb1a5, [I@2d6d8735, [I@ba4d54, [I@12bc6874, [I@de0a01f, [I@4c75cab9, [I@1ef7fe8e, [I@6f79caec]
[1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010]
[[1001, 1002, 1003, 1004, 1005, 1006, 1007, 1008, 1009, 1010], [2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010]]
2.按值传递与对象
java 里面,所有的“对象”都是引用类型的。如果自定义一个类,其中一个方法的返回值是一个对象,那么即使该对象是该类的私有成员,但因为返回了引用类型,所以仍可能在外部直接对该私有成员对象进行直接的修改。所以这种情况应返回一个拷贝值。
值得注意的是, java 的类的方法的参数是按值传递的。当参数是一个“对象”时,传递的是该对象的“引用”的拷贝。也就是说,如果在方法中交换两个“对象”类型的参数,退出方法后,那两个对象仍没有交换;但如果调用了该“对象”的方法以修改该“对象”的成员,退出方法后,该“对象”成功被修改了,因为参数是引用类型的。
在 C++ 中,初始化列表用于不能通过赋值来进行初始化、必须显式初始化的成员,比如 const 类型、没有默认构造函数的类。但在 java 中,“对象没有子对象,只有指向其他对象的指针“(《Java核心技术第10版》第125页),所以无需使用初始化列表。在声明一个对象的时候,只是分配了一个引用空间;调用 new 的时候分配内存空间。
3.类的访问
和 C++ 一样,一个类的方法不仅可以访问 this 的私有成员,还可以访问该类的其他实例的私有成员。
对于类、方法或变量,如果没有声明 public 或 private ,那么该类所在的包中的其他所有方法都可以访问该类。
子类的方法可以访问该子类的所有实例的【该子类的父类的 protected 成员】,但是不能访问其他类(父类、父类的其他子类)的【该子类的父类的 protected 成员】。 protected 成员还允许同包的其他类访问。
4.构造函数
java在类的构造函数中可以通过 this( ) 来调用该类的另一个构造函数!^ ^
不过这个语句必须写在该构造函数的最前面,且一个构造函数只能调用一次其他构造函数。
在 C++ 中,初始化列表还可以用于调用父类的构造函数。在 java 中需要使用 super 关键字,并且该调用语句需写在构造函数最前面。形如 super( ... ) .
5.动态绑定
一个声明为某个类 father 的变量 x ,可以赋值为该类的子类 child 的对象。如果子类重写了父类的方法 func( ),那么 x.func( ) 使用的是 father 类的 func( ) 还是 child 类的 func( ) 呢?
在 C++ 中,如果 func( ) 没有声明为虚函数,那么就是静态绑定, x 因为声明的时候是 father 类的,所以调用的是 father 类的 func( ) ;如果 func( ) 是虚函数,那么因为 x 实际指向一个 child 类型的对象,所以 x.func( ) 是 child 类的 func( ) .
在 java 中,默认是动态绑定。将方法声明为 final 类型可以阻止动态绑定。
注意,如果 child 类比 father 类多出一个方法 func2( ) ,那么 x 是不能调用 func2( ) 的,因为即使它实际指向 child 类,但它声明为 father 类。 x 不能使用 child 类比 father 类多出来的成员。