文章目录
1 10000以内的质数(素数)输出
/*
10000以内的质数(素数)输出 只能被1和它本身整除。--->从2开始到这个数-1结束为止都不能被这个数整除。
最小的质数是2
*/
public class PrimeNumberTest {
public static void main(String[] args) {
boolean isFlag = true;//内存空间加载的变量少
long start = System.currentTimeMillis();
for (int i = 2;i<=10000;i++){//遍历10000以内的自然数
//boolean isFlag = true;
for (int j=2;j<i;j++){
if(i % j==0){
isFlag = false;
}
}
if (isFlag == true)
System.out.println(i);
//重置isFlag
isFlag = true;
}
long end = System.currentTimeMillis();
System.out.println("用时:"+(end-start));//84
}
}
1.1 10000以内质数输出的算法优化一
/*
O(n) 与 O(n-1) 与 O(2n) 与 O(n/2)的时间复杂度都是O(n)级别,在一个量级上的
*/
public class PrimeNumberTest1 {
public static void main(String[] args) {
//标识i是否被j除尽,一旦除尽,修改其值
boolean isFlag = true;//内存空间加载的变量少
long start = System.currentTimeMillis();
for (int i = 2;i<=10000;i++){//遍历10000以内的自然数
//boolean isFlag = true;
for (int j=2;j<i;j++){ //j:被i去除
if(i % j==0){ //i被j除尽
isFlag = false;
break;//优化一:一旦发现被除尽的j 后边的j就不除了 此优化只对非质数有效
}
}
if (isFlag == true) {
System.out.println(i);
}
//重置isFlag
isFlag = true;
}
long end = System.currentTimeMillis();
System.out.println("用时:"+(end-start));//16
}
}
1.2 10000以内质数输出的算法优化二
O(n) 与 O(n-1) 与 O(2n) 与 O(n/2)的时间复杂度都是O(n)级别,在一个量级上的
*/
public class PrimeNumberTest2 {
public static void main(String[] args) {
//标识i是否被j除尽,一旦除尽,修改其值
boolean isFlag = true;//内存空间加载的变量少
int count = 0;//记录质数的个数
long start = System.currentTimeMillis();
for (int i = 2;i<=10000;i++){//遍历10000以内的自然数
//boolean isFlag = true;
//优化二:i开方 因为除不尽前面的数,后面的也就除不尽 临界值是平方根 此优化对质数有效(对非质数也有效只不过下面的break使得非质数到不了这一步)
for (int j=2;j<=Math.sqrt(i);j++){ //j:被i去除
if(i % j==0){ //i被j除尽
isFlag = false;
break;//优化一:一旦发现被除尽的j 后边的j就不除了 此优化只对非质数有效
}
}
if (isFlag == true) {
//System.out.println(i);//输出语句拖慢了程序时间
count++;
}
//重置isFlag
isFlag = true;
}
long end = System.currentTimeMillis();
System.out.println("质数个数"+count);
System.out.println("用时:"+(end-start));//2
}
}
2 鸡兔同笼共35只,脚94只,问分别多少只鸡兔
一共y只脚,定义脚为foot,则chicken*2+rabbit*4 ==y*/
public class Demo {
public static void main(String[] args) {
//鸡兔同笼,鸡兔一共35只,笼子里脚一共94只,请问分别有多少只兔子和多少只鸡?
int foot = 94;//笼子里一共94只脚
int sum = 35;//鸡兔一共35只
for (int chicken = 1; chicken <= foot / 2; chicken++) {//鸡的数量
int rabbit = sum - chicken;//兔子的数量
if(rabbit * 4 + chicken * 2 == foot){
System.out.println("兔子的只数为" + rabbit);
System.out.println("鸡的只数为 " + chicken);
}
}
}
}
3 证明多态是运行时行为
class Animal {
protected void eat() {
System.out.println("animal eat food");
}
}
class Cat extends Animal {
protected void eat() {
System.out.println("cat eat fish");
}
}
class Dog extends Animal {
public void eat() { System.out.println("Dog eat bone"); }
}
class Sheep extends Animal {
public void eat() { System.out.println("Sheep eat grass"); }
}
public class InterviewTest {
public static Animal getInstance(int key) {
switch (key) {
case 0:
return new Cat ();
case 1:
return new Dog ();
default:
return new Sheep ();
}
}
public static void main(String[] args) {
int key = new Random().nextInt(3);
System.out.println(key);
Animal animal = getInstance(key);
animal.eat();
}
}
4 单例饿汉式
public class SingletonTest {
//此为单例饿汉式
public static void main(String[] args) {
Singleton instance1 = Singleton.getInstance();
Singleton instance2 = Singleton.getInstance();
System.out.println(instance2 == instance1);
}
}
class Singleton {
//1 私有化构造器
private Singleton() {}
//2 内部创建类的对象
//5 (静态方法只能调静态的结构) 所以创建的对象也得是静态的
private static Singleton instance = new Singleton();
//3 提供公共的供外界调用的方法
//4 把此方法声明为静态的(然后instance报错言外之意创建了对象才能在堆空间加载它)
public static Singleton getInstance() {
return instance;
}
}
4.1 线程安全的单例懒汉式
public class SingletonTest1 {
//单例线程安全的懒汉式
public static void main(String[] args) {
Single instance1 = Single.getInstance();
Single instance2 = Single.getInstance();
System.out.println(instance1 == instance2);
}
}
class Single {
private Single() {}
//private static volatile Single instance = null;
private static Single instance = null;
public static Single getInstance() {
if (instance == null) {
synchronized (Single.class) {
if (instance == null) {
instance = new Single();
}
}
}
return instance;
}
}
5 静态代理
//静态代理:代理类和被代理类在编译期间就确定下来了
interface ClothFactory{
void produceCloth();
}
//代理类
class ProxyClothFactory implements ClothFactory{
private ClothFactory factory;//用被代理类对象进行实例化
public ProxyClothFactory(ClothFactory factory){
this.factory = factory;
}
@Override
public void produceCloth() {
System.out.println("代理工厂做一些准备工作");
factory.produceCloth();
System.out.println("代理工程做收尾工作");
}
}
//被代理类
class NikeClothFactory implements ClothFactory{
@Override
public void produceCloth() {
System.out.println("Nike工厂生产一批运动服");
}
}
public class StaticProxyTest {
public static void main(String[] args) {
ClothFactory nike = new NikeClothFactory();
//创建代理类的对象
ClothFactory proxyClothFactory = new ProxyClothFactory(nike);
proxyClothFactory.produceCloth();
}
}
5.1 动态代理(反射的应用)
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
interface ClothFactory{
void produceCloth();
}
class NikeClothFactory implements ClothFactory{
@Override
public void produceCloth() {
System.out.println("nike工厂生产衣服");
}
}
//反射的应用:动态代理举例
interface Human{
String getBelief();
void eat(String food);
}
//第1步
//被代理类
class SuperMan implements Human{
@Override
public String getBelief() {
return "I believe I can fly";
}
@Override
public void eat(String food) {
System.out.println("我喜欢吃"+food);
}
}
//问题一:如何根据加载到内存中的被代理类,动态地创建一个代理类及其对象
//问题二:当通过代理类的对象调用方法时,如何动态地去调用被代理类中的同名方法。
class ProxyFactory{
//调用此方法返回一个代理类的对象
public static Object getProxyInstance(Object obj){ //obj:被代理类的对象
MyInvocationHandler handler = new MyInvocationHandler();
handler.bind(obj);//第4.2步
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), handler);//第2步
}
}
class MyInvocationHandler implements InvocationHandler{//第3步
private Object obj;//需要使用被代理类的对象进行赋值 //第4.1步
public void bind(Object obj){
this.obj = obj;
}
//当我们通过代理类的对象调用方法a时,就会自动的调用如下的方法:invoke()
//将被代理类要执行的方法a的功能就声明在invoke()中
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//method:即为代理类对象调用的方法,此方法也就作为了被代理类对象要调用的方法
//obj:被代理类的对象
Object returnValue = method.invoke(obj, args);//第4步
//上述方法的返回值就作为当前类中的invoke()的返回值。
return returnValue;//第4.3步
}
}
public class ProxyTest {
public static void main(String[] args) {
SuperMan superMan = new SuperMan();
//proxyInstance:代理类的对象
Human proxyInstance =(Human) ProxyFactory.getProxyInstance(superMan);//像接口的匿名实现类 再强转 //第5步
String belief = proxyInstance.getBelief();//此方法会自动地调上面invoke(),invoke()中的method就是getBelief()
System.out.println(belief);
proxyInstance.eat("大众炒菜");//此方法会自动地调上面invoke(),invoke()中的参数method就是eat(),参数args就是"大众炒菜",参数obj就是superMan
System.out.println("****************************************");
NikeClothFactory nikeClothFactory = new NikeClothFactory();
ClothFactory proxyInstance1 = (ClothFactory) ProxyFactory.getProxyInstance(nikeClothFactory);
proxyInstance1.produceCloth();
}
//总结:编译时没有一个类叫代理类即代理类没有显式的定义,而是在运行时根据传过来的被代理类对象是谁,能动态地帮你创建代理类,体现了反射的动态性
//动态代理相比静态代理的优点:抽象角色中(接口)声明的所有方法都被转移到调用处理器一个集中的方法中处理,这样,我们可以更加灵活和统一的处理众多的方法。
}
6 斐波那契数列
import java.util.Scanner;
//已知斐波那契数列的前几个数为0,1,1,2,3,5...从第三项开始每一项等于前两项的和。请接收用户输入的整数n输出此数列的前n项
public class Faibonacci {
public static void main(String[] args) {
System.out.println("请输入您要测试的项数:");
int n = new Scanner(System.in).nextInt();
//判断n是否是不正常的范围
if(n<1){
System.out.println("输入数据有误!!!");
}
//n==1
if(n==1){
System.out.println(0);
}
//n==2
if(n==2){
System.out.println(0+"\t"+1);
}
//n==3
if(n==3){
System.out.println(0+"\t"+1+"\t"+1);
}
//拼接前n项
if(n>3){
System.out.print(0+"\t"+1+"\t"+1+"\t");
}
//循环输出后面的数据
int f1=1;
int f2=1;
int next=0;
for(int i=4;i<=n;i++){
next=f1+f2;
f1=f2;
f2=next;
System.out.print(next+"\t");
}
}
}
7 Comparable自然排序
import org.junit.Test;
import java.util.Arrays;
public class ComparableTest {
//自然排序对应的接口是Comparable对应的抽象方法compareTo(Object obj)
//定制排序对应的接口是Comparator对应的抽象方法compare(Object obj1,Object obj2)
@Test
public void test1(){
Product[]arr = new Product[5];
arr[0] = new Product("Huawei", 6299);
arr[1] = new Product("Xiaomi", 4999);
arr[2] = new Product("Vivo", 5999);
arr[3] = new Product("Iphone", 9999);
arr[4] = new Product("Honor", 6299);
Arrays.sort(arr);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
class Product implements Comparable { //商品类
private String name;//商品名称
private double price;//价格
public Product(String name, double price) {
this.name = name;
this.price = price;
}
public Product() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Product{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
@Override
//自然排序
public int compareTo(Object o) {
if (o ==this){
return 0;
}
if (o instanceof Product){
Product p = (Product) o;
int value = Double.compare(this.price,p.price);
if (value !=0){
return value;
}
return -this.name.compareTo(p.name);//加负号顺序相反
}
throw new RuntimeException("数据类型不匹配");
}
}
7.1 Comparator定制排序
import org.junit.Test;
import java.util.Arrays;
import java.util.Comparator;
public class ComparatorTest {
//自然排序对应的接口是Comparable对应的抽象方法compareTo(Object obj)
//定制排序对应的接口是Comparator对应的抽象方法compare(Object obj1,Object obj2)
@Test
public void test1(){
Product[]arr = new Product[5];
arr[0] = new Product("Huawei", 6299);
arr[1] = new Product("Xiaomi", 4999);
arr[2] = new Product("Vivo", 5999);
arr[3] = new Product("Iphone", 9999);
arr[4] = new Product("Honor", 6299);
//定制排序 创建一个实现了Comparator接口的实现类的对象
Comparator comparator = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Product && o2 instanceof Product){
Product p1 = (Product) o1;
Product p2 = (Product) o2;
return Double.compare(p1.getPrice(), p2.getPrice());
}
throw new RuntimeException("类型不匹配");
}
};
Comparator comparator1 = new Comparator() {
@Override
public int compare(Object o1, Object o2) {
if (o1 instanceof Product && o2 instanceof Product){
Product p1 = (Product) o1;
Product p2 = (Product) o2;
return p1.getName().compareTo(p2.getName());
}
throw new RuntimeException("类型不匹配");
}
};
Arrays.sort(arr, comparator1);
for (int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
}
}
}
class Product { //商品类
private String name;//商品名称
private double price;//价格
public Product(String name, double price) {
this.name = name;
this.price = price;
}
public Product() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
@Override
public String toString() {
return "Product{" +
"name='" + name + '\'' +
", price=" + price +
'}';
}
}
8 子类重写的方法异常不大于父类的
import java.io.FileNotFoundException;
import java.io.IOException;
public class OverrideTest {
//子类重写的方法的异常类型不能大于父类的被重写的方法的
//子类重写方法的返回值类型不得大于父类的被重写的方法的
public static void main(String[] args) {
Father f = new Son();
try {
f.method1();
}catch (IOException e){//编译看左边,真正运行时调的是子类的方法,子类方法如果抛的异常类型就进不去catch,要想进得去旧的不大于catch内的异常类型。(多态)
e.printStackTrace();
}
Number n = f.method3();//(多态)实际执行时返回的是Number的子类的对象
}
}
class Father{
public void method1() throws IOException{
}
public void method2(){
}
public Number method3(){
return null;
}
}
class Son extends Father{
public void method1()throws FileNotFoundException{
}
// public void method2()throws FileNotFoundException{}//父类没有抛编译时异常子类更不能抛,此方法要有编译时异常只能try catch
public Integer method3(){
return null;
}
}
9 算法之快速排序
10 斗地主自动出牌算法
写一个斗地主游戏的自动出牌算法,即找出一手牌中跟上家牌型相同且刚好比对方大一点的牌的组合。不需要实现细节,用一两屏代码展示思路。语言不限,考察的是你写程序的方式。(对不了解斗地主规则的人,这里简单介绍下,斗地主的牌型有单牌、对子、三条、五张或以上连张、三对或以上连对、三带一、三带二、连三、连三带二、炸弹等等)提示:这不是教科书上那种超级简化的题目,而是现实世界的复杂问题,需求随时可以变得更复杂,代码容易理解和修改很重要,不需要细节,但尽量别漏条件。
11 编码
public static void main(String[] args) throws UnsupportedEncodingException {
String str = "小朋友";
byte[] bytes = str.getBytes();
System.out.println(Arrays.toString(bytes));
String str1 = "小朋友";
String str2 = "除夕快乐";
byte[] byte1 = str1.getBytes("GBK");
byte[] byte2 = str2.getBytes("GBK");
System.out.println(Arrays.toString(byte1));
System.out.println(Arrays.toString(byte2));
}
12 解码
public static void main(String[] args) throws UnsupportedEncodingException {
byte[] bytes1 = {-64, -18, -55, -70};
byte[] bytes2 = { -77, -3, -49, -90, -65, -20, -64, -42};
String s1 = new String(bytes1,"GBK");
String s2 = new String(bytes2,"GBK");
System.out.println(s1+"\n"+s2);
}
13 打印正三角行加倒三角形
public class Sw {
public static void main(String[] args) {
//上半部分
for(int i = 1;i <= 5; i++){
//-
for(int j =1;j<=10-2*i;j++){
System.out.print(" ");
}
//*
for(int k = 1;k<=2*i-1 ;k++){
System.out.print("* ");
}
System.out.println();
}
//下半部分
for(int i =1;i<=4;i++){
//-
for(int j=1;j<=2*i;j++){
System.out.print(" ");
}
// for(int k=9-2*i;k>=1;k--){
// System.out.print("* ");
// }
//*
for(int k=1;k<=9-2*i;k++){
System.out.print("* ");
}
System.out.println();
}
}
}