I am very new to this programming stuff. I am currently taking Data Structures in Java. I have an assignment where I have to replicate a given Subway system. I am supposed to do it in 3 classes (Station, Route and Subway). Could someone please direct me in the right direction in regards to starting this project? Below are my instructions. Thank you very much.
Implement a class called Station that contains information about a particular station. This class should allow to set at least the name of the station. Each station is unique within the subway system.
Implement a class called Route that stores information about a particular route. This Route class should allow to add stations/remove stations from the route. A route has a name.
Implement a class called Subway. This Subway class should allow to add and delete Route objects.
Implement the following subway system in your application.
Now, develop a method in the Subway class that given two stations passed as parameters that belongs to a Subway object, it returns a list of stations that the user will traverse to go from one station to the other. Assume that there are no loops in the system. The method signature is as follows:
public List getRouteBetweenStations(Station a, Station b)
Here's where I am and I'm not even sure it's correct
public class **Station**
{
String station;
private final String STATION1 = "140";
private final String STATION2 = "134";
private final String STATION3 = "Unicentro";
private final String STATION4 = "100";
private final String STATION5 = "30";
private final String STATION6 = "R";
private final String STATION7 = "Marsella";
private final String STATION8 = "Mu";
private final String STATION9 = "Bosa";
private final String STATION10 = "Germania";
private final String STATION11= "19";
private final String STATION12 = "Sabana";
private final String STATION13 = "Espec";
private final String STATION14 = "F";
private final String STATION15 = "Gu";
private final String STATION16 = "Santiago";
private final String STATION17 = "SENA";
private final String STATION18 = "Timiza";
public void setStation(String stops)
{
station = stops;
}
}
import java.util.ArrayList;
import java.util.List;
public class **Route**
{
List<String> route1 = new ArrayList<>();
List<String> route2 = new ArrayList<>();
List<String> route3 = new ArrayList<>();
List<String> route4 = new ArrayList<>();
List<String> route5 = new ArrayList<>();
route1.add ("140"); (**here I am getting an error here telling me that "package route1 does not exist**)
Again, any help you can give me is greatly appreciated
The subway should contain routes and routes should contain stations. When you see contains or add and delete in programming execises this most often implies you will need a list to for the classes.
What is the reason for the string constants in your Station class?
This question already has answers here:
Java Stream: find an element with a min/max value of an attribute
(9 answers)
Closed 5 years ago.
I want to find max value in java list using java8 lambda expression,
so, I have a Class called TicketMaster and item table is TicketMasterLog ,in TicketMasterLog class I have StatusMaster Class statusId reference column, so here i want to find max statusId in TicketMasterLog List, below i'll give my code please refer
#Entity
#Table(name="ticket_master")
#NamedQuery(name="TicketMaster.findAll", query="SELECT t FROM TicketMastert")
public class TicketMaster implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name="TICKET_ID", unique=true, nullable=false, length=10)
private String ticketId;
//bi-directional many-to-one association to TicketMasterLog
#OneToMany(mappedBy="ticketMaster",cascade=CascadeType.ALL)
private List<TicketMasterLog> ticketMasterLogs;
//getters and stters
}
and TicketMasterItem Table is
#Entity
#Table(name="ticket_master_log")
#NamedQuery(name="TicketMasterLog.findAll", query="SELECT t FROM TicketMasterLog t")
public class TicketMasterLog implements Serializable {
private static final long serialVersionUID = 1L;
#EmbeddedId
private TicketMasterLogPK id;
//bi-directional many-to-one association to StatusMaster
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="STATUS_ID")
private StatusMaster statusMaster;
//bi-directional many-to-one association to TicketMaster
#ManyToOne(fetch=FetchType.LAZY)
#JoinColumn(name="TICKET_ID", nullable=false, insertable=false, updatable=false)
private TicketMaster ticketMaster;
//getters and setters
}
and StatusMaster Table is
#Entity
#Table(name="status_master")
#NamedQuery(name="StatusMaster.findAll", query="SELECT s FROM StatusMaster s")
public class StatusMaster implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name="STATUS_ID", unique=true, nullable=false, length=10)
private String statusId;
#Column(name="STATUS_NAME", length=45)
private String statusName;
//bi-directional many-to-one association to TicketMasterLog
#OneToMany(mappedBy="statusMaster")
private List<TicketMasterLog> ticketMasterLogs;
//getters and setters...
Now I have a TicketMasterlog List
List<TicketMasterLog> tl = //some objects;
so in that list I want find max status id value
thanking you.
You can use:
Stream<TicketMasterLog> ticketMasterLogStream = tl.stream();
TicketMasterLog max = ticketMasterLogStream.reduce((a,b)->
a.getStatusId.compareTo(b.getStatusId) > 0 ? a:b;
).get()
I have the following simple DynamoDBDao which contains one method that queries an index and returns a map of results.
import com.amazonaws.services.dynamodbv2.document.*;
public class DynamoDBDao implements Dao{
private Table table;
private Index regionIndex;
public DynamoDBDao(Table table) {
this.table = table;
}
#PostConstruct
void initialize(){
this.regionIndex = table.getIndex(GSI_REGION_INDEX);
}
#Override
public Map<String, Long> read(String region) {
ItemCollection<QueryOutcome> items = regionIndex.query(ATTR_REGION, region);
Map<String, Long> results = new HashMap<>();
for (Item item : items) {
String key = item.getString(PRIMARY_KEY);
long value = item.getLong(ATTR_VALUE);
results.put(key, value);
}
return results;
}
}
I am trying to write a unit test which verifies that when the DynamoDB index returns an ItemCollection then the Dao returns the corresponding results map.
public class DynamoDBDaoTest {
private String key1 = "key1";
private String key2 = "key2";
private String key3 = "key3";
private Long value1 = 1l;
private Long value2 = 2l;
private Long value3 = 3l;
#InjectMocks
private DynamoDBDao dynamoDBDao;
#Mock
private Table table;
#Mock
private Index regionIndex;
#Mock
ItemCollection<QueryOutcome> items;
#Mock
Iterator iterator;
#Mock
private Item item1;
#Mock
private Item item2;
#Mock
private Item item3;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(table.getIndex(DaoDynamo.GSI_REGION_INDEX)).thenReturn(regionIndex);
dynamoDBDao.initialize();
when(item1.getString(anyString())).thenReturn(key1);
when(item1.getLong(anyString())).thenReturn(value1);
when(item2.getString(anyString())).thenReturn(key2);
when(item2.getLong(anyString())).thenReturn(value2);
when(item3.getString(anyString())).thenReturn(key3);
when(item3.getLong(anyString())).thenReturn(value3);
}
#Test
public void shouldReturnResultsMapWhenQueryReturnsItemCollection(){
when(regionIndex.query(anyString(), anyString())).thenReturn(items);
when(items.iterator()).thenReturn(iterator);
when(iterator.hasNext())
.thenReturn(true)
.thenReturn(true)
.thenReturn(true)
.thenReturn(false);
when(iterator.next())
.thenReturn(item1)
.thenReturn(item2)
.thenReturn(item3);
Map<String, Long> results = soaDynamoDbDao.readAll("region");
assertThat(results.size(), is(3));
assertThat(results.get(key1), is(value1));
assertThat(results.get(key2), is(value2));
assertThat(results.get(key3), is(value3));
}
}
My problem is that items.iterator() does not actually return Iterator it returns an IteratorSupport which is a package private class in the DynamoDB document API. This means that I cannot actually mock it as I did above and so I cannot complete the rest of my test.
What can I do in this case? How do I unit test my DAO correctly given this awful package private class in the DynamoDB document API?
First, unit tests should never try to verify private state internal to an object. It can change.
If the class does not expose its state via non-private getter methods, then it is none of your test's business how it is implemented.
Second, why do you care what implementation the iterator has?
The class has fulfilled its contract by returning an iterator (an interface)
which when iterated over will return the objects it is supposed to.
Third, why are you mocking objects that you don't need to?
Construct the inputs and outputs for your mocked objects, don't mock them; it is unnecessary.
You pass a Table into your constructor? Fine.
Then extend the Table class to make whatever protected methods for whatever you need.
Add protected getters and/or setters to your Table subclass.
Have them return hard coded values if necessary. They don't matter.
Remember, only test one class in your test class.
You are testing the dao not the table nor the index.
Dynamodb api has a lot of such classes which can not easily be mocked. This results in lot of time spent on writing complex tests and changing features are big pain.
I think, for this case a better approach will be not try to go the traditional way and use DynamodbLocal library by the AWS team - http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/Tools.DynamoDBLocal.html
This is basically an in memory implementation of DyanamoDB. We had written our tests such that during unit test initialization, DyanmodbLocal instance would be spawned and tables would be created. This makes the testing a breeze. We have not yet found any bugs in the library and it is actively supported and developed by AWS. Highly recommend it.
One possible workaround is to define a test class which extends IteratorSupport in the same package that it is present in, and define the desired behavior
You can then return an instance of this class through your mock setup in the test case.
Of course, this is not a good solution, but simply a workaround for the same reasons that #Jeff Bowman mentioned in the comment.
May be it'd be better to extract ItemCollection retrieval to the separate method?
In your case it may look as follows:
public class DynamoDBDao {
protected Iterable<Item> readItems(String region) { // can be overridden/mocked in unit tests
// ItemCollection implements Iterable, since ItemCollection-specific methods are not used in the DAO we can return it as Iterable instance
return regionIndex.query(ATTR_REGION, region);
}
}
then in unit tests:
private List<Item> mockItems = new ArrayList<>(); // so you can set these items in your test method
private DynamoDBDao dao = new DynamoDBDao(table) {
#Override
protected Iterable<Item> readItems(String region) {
return mockItems;
}
}
When you use when(items.iterator()).thenReturn(iterator); Mockito sees the items as ItemCollection which causes the compilation error. In your test case, you want to see ItemCollection as just an Iterable. So, the simple solution is to cast the items as Iterable like below:
when(((Iterable<QueryOutcome>)items).iterator()).thenReturn(iterator);
Also make your iterator as
#Mock
Iterator<QueryOutcome> iterator;
This should fix the code without warning :)
If this fixes the problem, please accept the answer.
You can test your read method by using fake objects like this :
public class DynamoDBDaoTest {
#Mock
private Table table;
#Mock
private Index regionIndex;
#InjectMocks
private DynamoDBDao dynamoDBDao;
public DynamoDBDaoTest() {
}
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
when(table.getIndex(GSI_REGION_INDEX)).thenReturn(regionIndex);
dynamoDBDao.initialize();
}
#Test
public void shouldReturnResultsMapWhenQueryReturnsItemCollection() {
when(regionIndex.query(anyString(), anyString())).thenReturn(new FakeItemCollection());
final Map<String, Long> results = dynamoDBDao.read("region");
assertThat(results, allOf(hasEntry("key1", 1l), hasEntry("key2", 2l), hasEntry("key3", 3l)));
}
private static class FakeItemCollection extends ItemCollection<QueryOutcome> {
#Override
public Page<Item, QueryOutcome> firstPage() {
return new FakePage();
}
#Override
public Integer getMaxResultSize() {
return null;
}
}
private static class FakePage extends Page<Item, QueryOutcome> {
private final static List<Item> items = new ArrayList<Item>();
public FakePage() {
super(items, new QueryOutcome(new QueryResult()));
final Item item1= new Item();
item1.with(PRIMARY_KEY, "key1");
item1.withLong(ATTR_VALUE, 1l);
items.add(item1);
final Item item2 = new Item();
item2.with(PRIMARY_KEY, "key2");
item2.withLong(ATTR_VALUE, 2l);
items.add(item2);
final Item item3 = new Item();
item3.with(PRIMARY_KEY, "key3");
item3.withLong(ATTR_VALUE, 3l);
items.add(item3);
}
#Override
public boolean hasNextPage() {
return false;
}
#Override
public Page<Item, QueryOutcome> nextPage() {
return null;
}
}
ItemCollection<QueryOutcome> items = new ItemCollection<QueryOutcome>() {
#Override
public Integer getMaxResultSize() {
return 0;
}
#Override
public Page<Item, QueryOutcome> firstPage() {
return null;
}
};
Mockito.when(index.query(Mockito.any(QuerySpec.class))).thenReturn(items);
QueryResult queryResult = new QueryResult();
Mockito.when(dynamoDBClient.query(Mockito.any(QueryRequest.class))).thenReturn(queryResult);
I've the following situation:
class A {
private String name;
private List<R> rs = new ArrayList<R>();
//get, set
}
class R {
private String content;
//get, set
}
class AH {
private String name;
private List<RH> rs = new ArrayList<RH>();
//get, set
}
class RH {
private String content;
//get, set
}
How to configure dozer to map no only name field (it's mapped correctly) from A to AH but also map automatically collection of R to collection of RH?
Dozer handles this automatically. My fault, there were no getters and setters.
I have a DC LoadResultwith DataMemebers of type List<string>
public partial class LoadResult : ServiceResult
{
[DataMember]
public List<string> Country { get; set; }
[DataMember]
public List<string> AuditStatus { get; set; }
}
trying to fill in these values in my DO by doing the following steps.
LoadResult LResult = new LoadResult ();
//Code to connect to database , retrive appropriate values
string x = "some string value retrieved from database";
LResult.Country.Add(x);
the last line of code throws me an object reference not set to an instance error, this might be some fundamental thing that i have missed here, but since i have initialized the DC class with the new keyword, i am clueless as to what the error is, Can you help me out here
you need to do
LResult.Country = new List<string>();
before you add values