Java入门

一、安装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 类多出来的成员。

posted on 2021-08-30 14:51  Narh  阅读(37)  评论(0编辑  收藏  举报

导航