题目:农场一头小母牛,每年生头小母牛,母牛5岁产母牛,20年上多少牛?

目的:1、考验初学者面向对象设计理念。2、考验初学者的逻辑思维能力以及计算能力。

注:不考虑其他现实中的逻辑,比如没有公牛怎么生母牛,这样的想法。就题论题,主要是用此案例了解面向对象的精髓。

思路:

1、首先想到的是创建一个Cow的母牛类。母牛至少有一个属性,那就是年龄,用年龄类判断后面生的小牛是否在当前年度具备了生小牛的能力。

2、其次会想到,创建一个birthCow或者produceCow的方法。这个方法到底放到Cow类中,还是新建一个农场Farm类,放到农场类中。答案是,都可以。

    为了层次显示的更为清晰,本案例就把生产小母牛的方法,写在农场类中。

3、最后,写出核心代码:算法。

   在birthCow(int years)运行后发现,报ConcurrentModificationException错了。思维逻辑没有问题,程序抛出了异常,不允许在for循环中修改被循环的对象。

   根据报错原因,改装birthCow为:birthCow2(int years);(改装思路,不允许改变For循环的对象,那么我们就建一个临时对象)。

注:核心代码是Fram类中的birthCow(),birthCow2()是在此基础上改装的。birthCow()能看懂,birthCow2()就很容易看懂了。

4、具体实现代码,如下:

a)创建母牛类,一个年龄属性就够用了。

public class Cow {
	public int age;
	public Cow() {
		super();
	}

	public Cow(int age) {
		super();
		this.age = age;
	}

	public int getAge() {
		return age;
	}

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

b)创建农场类,并提供生小母牛的方法。同时给农场初始化一头老母牛(年龄大于等于5就可以)。


//农场类
public class Farm {
	
   public static List <Cow> listCow=new ArrayList<Cow>();
   static {
		listCow.add(new Cow(5));//初始化一头具有生育能力的母牛
	}
	
	public Farm() {
		super();
	}
	
	//该方法报:java.util.ConcurrentModificationException
	//原因:系统不允许for循环的对象的同时,对对象进行修改。比如:给牛的年龄增加1
	public List <Cow> birthCow(int years) {
		for(int i=1;i<=years;i++) {
			
			//每循环一次,过滤一下具有生育能力的牛,让它生一头牛,且给所有已存在的牛年龄增加1
			for (Cow cow : listCow) {
				cow.setAge(cow.getAge()+1);//年龄+1
				if(cow.getAge()/5>=1) {
					listCow.add(new Cow(1));//生母牛一头
				}
				System.out.println("第"+i+"年牛的个数"+listCow.size());
			}
		}
		return listCow;
	}
	
	//改装后的方法
	public List <Cow> birthCow2(int years) {
		for(int i=1;i<=years;i++) {
			
			List <Cow> tempCows=new ArrayList<Cow>();//提供一个临时集合存放农场的牛
			int nowCount=0;//存放每年新生小母牛的数量
			//每循环一次,过滤一下具有生育能力的牛,让它生一头牛,且给所有已存在的牛年龄增加1
			for (Cow cow : listCow) {				
				cow.setAge(cow.getAge()+1);//原有奶牛的年龄+1
                tempCows.add(cow);
				if(cow.getAge()/5>=1) {
					tempCows.add(new Cow(1));//生母牛一头
					nowCount+=1;
				}
			}
			System.out.println("第"+i+"年原有牛个数:"+""+(tempCows.size()-nowCount)+" ;新增牛个数:"+nowCount+""+" ;牛的总个数:"+tempCows.size());
			listCow=tempCows;
		}
		return listCow;
	}
	
}

c)创建带有main方法的测试类:MainTest

public class MainTest {
	public static void main(String[] args) {
		Farm farm=new Farm();
		int count=farm.birthCow(20).size();
		//int count=farm.birthCow2(20).size();
		System.out.println(count);
	}
}

特别提示:farm.birthCow2()是最终要的答案。

farm.birthCow是个引子,便于理解。

d1)farm.birthCow运行(报错)结果。

Exception in thread "main" 第1年牛的个数2
java.util.ConcurrentModificationException
	at java.util.ArrayList$Itr.checkForComodification(ArrayList.java:901)
	at java.util.ArrayList$Itr.next(ArrayList.java:851)
	at com.xp.cow.model.Farm.birthCow(Farm.java:24)
	at com.xp.cow.model.MainTest.main(MainTest.java:6)

d2)改装后的farm.birthCow2的正确运行结果。

public class MainTest {
	public static void main(String[] args) {
		Farm farm=new Farm();
		//int count=farm.birthCow(20).size();
		int count=farm.birthCow2(20).size();
		System.out.println(count);
	}
}
第1年原有牛个数:1 ;新增牛个数:1 ;牛的总个数:2
第2年原有牛个数:2 ;新增牛个数:1 ;牛的总个数:3
第3年原有牛个数:3 ;新增牛个数:1 ;牛的总个数:4
第4年原有牛个数:4 ;新增牛个数:1 ;牛的总个数:5
第5年原有牛个数:5 ;新增牛个数:2 ;牛的总个数:7
第6年原有牛个数:7 ;新增牛个数:3 ;牛的总个数:10
第7年原有牛个数:10 ;新增牛个数:4 ;牛的总个数:14
第8年原有牛个数:14 ;新增牛个数:5 ;牛的总个数:19
第9年原有牛个数:19 ;新增牛个数:7 ;牛的总个数:26
第10年原有牛个数:26 ;新增牛个数:10 ;牛的总个数:36
第11年原有牛个数:36 ;新增牛个数:14 ;牛的总个数:50
第12年原有牛个数:50 ;新增牛个数:19 ;牛的总个数:69
第13年原有牛个数:69 ;新增牛个数:26 ;牛的总个数:95
第14年原有牛个数:95 ;新增牛个数:36 ;牛的总个数:131
第15年原有牛个数:131 ;新增牛个数:50 ;牛的总个数:181
第16年原有牛个数:181 ;新增牛个数:69 ;牛的总个数:250
第17年原有牛个数:250 ;新增牛个数:95 ;牛的总个数:345
第18年原有牛个数:345 ;新增牛个数:131 ;牛的总个数:476
第19年原有牛个数:476 ;新增牛个数:181 ;牛的总个数:657
第20年原有牛个数:657 ;新增牛个数:250 ;牛的总个数:907
907

答案:907

5、总结。

本案例是自己摸索,并改装的,然后对比网上提供的答案,大同小异。有的会把生母牛的方法拆分的更细,没有标准答案。

重要的是面向对象的设计思路,和正确的得数907.

 

更多推荐