0

So i am doing a first year university assignment question and i am going to be honest about it. I just want to make things clear before some of you come down-voting my question. I don't want complete code, i just want some help with a few things.

The question is divided into two parts. The first part is to write a Nucleotide class whose constructor has two properties. A single character called base that has to be either 'a' or 'c' or 'g' or 't' otherwise it should be 'n' and a boolean called degenerate.

My code for this part is here:

class Nucleotide { private char base; private boolean degenerate; public nucleotide(char base, boolean degenerate){ if(base != ‘a’ || base != ‘c’ || base != ‘g’ || base != ’t’){ this.base = ’n’; } else { this.base = base; } this.degenerate = degenerate; } } 

The next part of the question says to use the Nucleotide object and create a new Bacteria class. An instance of bacteria consists of a genome (a collection of nucleotides), and a species (a String).

You must create a constructor which accepts a String and a collection, and uses those to initialize the species and the collection of nucleotides. My code for this part is here:

class Bacteria { //private ArrayList<Nucleotide> genome; private String species; public Bacteria(String species, ArrayList<Nucleotide> genome) { genome = new ArrayList<Nucleotide>(); this.species = species; } 

My problem starts with the next step which asks us to write an instance method that performs deep copy and returns an instance of Bacteria.

public Bacteria binaryFission() {

How can i perform deep copy without serialization and reflection. I hardly know anything about those things.

Again i need pointers or the basic idea of how to go about completing the binaryFission() method. I have gone through several deep copy questions that are on SO but none of them are relevant to my question so i don't believe that i am asking a duplicate question. I am happy to provide more details though.

7
  • Why have you commented out //private ArrayList<Nucleotide> genome;? Commented Oct 28, 2016 at 23:11
  • Create a new list. Iterate through the nucleatides, and create a copy of each one. Add the copy to the new list, then create a new Bacteria instance by calling the constructor with that new list. You don't need to make a copy of the string, because it's immutable and can thus be safely shared between instances. Commented Oct 28, 2016 at 23:12
  • Because that would be duplicating the code, i believe. I have that code in the constructor as well. By getting the constructor's ArrayList, i can initialize the list from there. Is my logic wrong for that part? @Bohemian Commented Oct 28, 2016 at 23:14
  • You need to learn the basics and learn the difference between a field, a local variable, and an argument. Your constructor takes a list as argument, but completely ignores it and even overwrites it by a new empty list. You need to do something with the argument, or store it for later use in a field, otherwise that argument is useless. Commented Oct 28, 2016 at 23:17
  • I am just doing this part in my constructor You must create a constructor which accepts a String and a collection, and uses those to initialize the species and the collection of nucleotides. That is also one of the reason i commented out the instance variable of genome. If i uncomment genome and get a list in the constructor then how will i initialize them? @JBNizet Commented Oct 28, 2016 at 23:21

2 Answers 2

1

This is the way to do it manually

public Bacteria binaryFission() { String speciesClone = this.species; ArrayList<Nucleotide> genomeClone = new ArrayList<Nucleotide>(); //now iterate over the existing arraylist and clone each Nucleotide for(int index = 0; index < this.genome.size(); index++) { genomeClone.add(new Nucleotide( genome.get(index).getBase(), //needs to be added to the Nucleotide class to retrieve the base variable genome.get(index).getDegenerate() //needs to be added to be allowed to get its degenerate )); } return new Bacteria(speciesClone, genomeClone); } 

FYI - you'll need to add getters for your Nucleotide class private variables in order for this to work since they are private and Bacteria won't have access to their values without them.

Sign up to request clarification or add additional context in comments.

2 Comments

Why don't you use a foreach loop instead of using an indexed loop? It would make the code much cleaner.
Yeah, and that's a terrible idea: they're more verbose, more error-prone, and terribly inefficient with linked lists.
1

Since Nucleotide has no setters, and its fields are primitive, it is effectively immutable (can't be changed and therefore safe to "reuse"). You would be better to make the fields final to formally make it immutable.

All you need to make a deep copy is to make a shallow copy of your Nucleotide list and use that in your new Bacteria. You can make a copy like this:

List<Nucleotide> copy = new ArrayList<>(genome); 

You could create a simple factory method on Bacteria that returns a deep copy of itself:

public Bacteria copy() { return new Bacteria(species, new ArrayList<>(genome)); } 

3 Comments

That was my first thought, but given that the posted code doesn't compile, and doesn't have any method making the class usable, it's hard to say that it's indeed immutable in reality.
@JBN All true, but if it were useless, that fact would be discovered soon enough by OP and he would fix that. Or it could be an inner class that has its fields access directly, or the getters could just be omitted. In any event, primitive (final) fields is the important bit here.
I think you're very optimistic :-)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.