This is my starting code for a van rental database.
List<String> manual = new LinkedList<>();
List<String> automatic = new LinkedList<>();
List<String> location = new LinkedList<>();
manual.add("Queen");
manual.add("Purple");
manual.add("Hendrix");
automatic.add("Wicked");
automatic.add("Zeppelin");
automatic.add("Floyd");
automatic.add("Ramones");
automatic.add("Nirvana");
location.add("CBD");
location.add("Penrith");
location.add("Ceremorne");
location.add("Sutherland");
How can I link the cars to the location.
For example, location CBD has Wicked,Zepplin and Floyd, and Penrith has Queen.
So if the command line arguement has "Print CBD" then it must show the vans available in CBD.
Any help will be appreciated.
This is hardly a database. They are just three separate data pieces. Use some object-oriented design technique to create classes, such as a class called Van. For example, it's not java code exactly, just for example.
Class Van {
string name;
VanType type; // e.x, Enum {auto, manual}
Location location; // another class
}
I think you would be better off using the approach explained In This Post. I believe this would be a much clearer implementation.
I hope this helps.
Ok thats the code.
We are using only linked list as you wanted.
(linked list keeps track on the input order so we are using that too)
As it is one to many relation we should have some kind of "foreign key" so we can see the related object. For each car you add no matter manual or auto, you should add a key for the location as you can see below
for example rels[0] = 3; means that your first car will have relation with 4th object of the locations list. thats implemented in the code - take a look.
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
public class TestMain {
public static void main(String[] args) {
List<String> manual = new LinkedList<String>();
List<String> automatic = new LinkedList<String>();
List<String> location = new LinkedList<String>();
int[] rels = new int[8];
//cars with relations
rels[0] = 1;
manual.add("Queen");
rels[1] = 1;
manual.add("Purple");
rels[2] = 1;
manual.add("Hendrix");
rels[3] = 1;
automatic.add("Wicked");
rels[4] = 0;
automatic.add("Zeppelin");
rels[5] = 0;
automatic.add("Floyd");
rels[6] = 1;
automatic.add("Ramones");
rels[7] = 2;
automatic.add("Nirvana");
//key-0
location.add("CBD");
//key-1
location.add("Penrith");
//key-2
location.add("Ceremorne");
//key-3
location.add("Sutherland");
//here is the value that you have from your input args[] for example
String desiredLocation = "CBD";
int index = getLocationIndex(location, desiredLocation);
//if desired location not found we will print nothing
if(index==-1)return;
List mergedCars = new LinkedList<String>();
mergedCars.addAll(manual);
mergedCars.addAll(automatic);
for (int i = 0; i < rels.length; i++) {
if(index == rels[i])
{
System.out.println(mergedCars.get(i));
}
}
}
private static int getLocationIndex(List<String> location, String desiredLocation) {
int counter=0;
for (Iterator iterator = location.iterator(); iterator.hasNext();) {
String temp = (String) iterator.next();
if(temp.equals(desiredLocation))
{
return counter;
}
counter++;
}
return -1;
}
}
Related
I'm working with a large set of imported data and retrieving certain parts of it in the main method with 2 classes(WeatherStation, WeatherReading).The data is temperature readings at loads of weather stations(station id, name, lat, lon, year, time, temp etc) I made a third class (SoloSiteIds) whose sole purpose was to return a whole and complete ArrayList of the site ids with no duplication. But I cannot import the ArrayList from the other class into my main method. My SoloSiteIds class looks like this:
public class SoloSiteIds {
static ArrayList <Integer> siteIds = new ArrayList <Integer>();
public SoloSiteIds() {
}
public SoloSiteIds( ArrayList <Integer> siteIds) {
String[] weatherData = WeatherData.getData();{ // get the weather data
for (int i = 1; i < weatherData.length; i++) {
String line = weatherData[i];
String[] elements = line.split(","); // Split the data at ",
String siteid = elements[0]; // convert all the site id's at index 0 to integers
int id = Integer.parseInt(siteid);
if(!siteIds.contains(id)) {
siteIds.add(id);
}
this.siteIds=siteIds;
}
}
}
public static ArrayList<Integer> getSiteIds() {
return siteIds;
}
public ArrayList<Integer> setSiteIds(ArrayList<Integer> siteIds) {
return this.siteIds = siteIds;
}
}
The main method where I am trying to import the ArrayList "siteIds" looks like this:
WeatherStation thisStation = new WeatherStation (id, name, lat, lon);
WeatherReading thisReading = new WeatherReading(year, month, date, hour, windSpeed, temp);
SoloSiteIds siteList= new SoloSiteIds();
String[] weatherData = WeatherData.getData();{ // get the weather data
for (int i = 1; i < weatherData.length; i++) {
String line = weatherData[i];
String[] elements = line.split(","); // Split the data at ","
String siteid = elements[0]; // convert all the site id's at index 0 to integers
id = Integer.parseInt(siteid);
thisStation.setId(id);
thisStation.setName(elements[1]);
//parse the different elements into different data types
String stringLat = elements[2];
lat= Double.parseDouble(stringLat);
lat = thisStation.setLat(lat);
lat=thisStation.setLat(lat);
String stringLon = elements[3];
lon= Double.parseDouble(stringLon);
lat = thisStation.setLon(lon);
lat=thisStation.setLon(lon);
String stringTemp=elements[9];
temp=Double.parseDouble(stringTemp);
temp=thisReading.setTemp(temp);
Only the top part is relevant. I have tried lots of different variation of .set and .get using "thisList" instance and a new ArrayList like
ArrayList<Integer> siteIds = thisList.setSiteIds();
ArrayList<Integer> siteIds= SoloSiteIds.getSiteIds();
thisList=Siteids.setSiteIds();
thisList=SingleSoloSites.setSiteIds();
etc etc. This might look stupid but im just showing Ive tried numerous things and i am stuck
Thanks
I believe your problem is that you are initializing siteIds as an empty Arry list but you are not setting the data in a static way (the set Method is not static).
As far as I am aware of your situation, I belive that the SoloSiteIds class is unnescessary. I would solve your problem with an ArrayList declared in your main class and initialize with a getSoleIds() method also declared in your main class.
The getSoleIds() Method should contain the code currently in the SoleSiteIds initializer.
I am trying to iterate through many arrays, two at a time. They contain upwards of ten-thousand entries each, including the source. In which I am trying to assign each word to either a noun, verb, adjective, or adverb.
I can't seem to figure a way to compare two arrays without writing an if else statement thousands of times.
I searched on Google and SO for similar issues. I couldn't find anything to move me forward.
package wcs;
import dictionaryReader.dicReader;
import sourceReader.sourceReader;
public class Assigner {
private static String source[], snArray[], svArray[], sadvArray[], sadjArray[];
private static String nArray[], vArray[], advArray[], adjArray[];
private static boolean finished = false;
public static void sourceAssign() {
sourceReader srcRead = new sourceReader();
//dicReader dic = new dicReader();
String[] nArray = dicReader.getnArray(), vArray = dicReader.getvArray(), advArray = dicReader.getAdvArray(),
adjArray = dicReader.getAdjArray();
String source[] = srcRead.getSource();
// Noun Store
for (int i = 0; i < source.length; i++) {
if (source[i] == dicReader.getnArray()[i]) {
source[i] = dicReader.getnArray()[i];
}else{
}
}
// Verb Store
// Adverb Store
// Adjective Store
}
}
Basically this is a simpler way to get a list of items that are in both Lists
// construct a list of item for first list
List<String> firstList = new ArrayList<>(Arrays.asList(new String[0])); // add items
//this function will only keep items in `firstList` if the value is in both lists
firstList.retainAll(Arrays.asList(new String[0]));
// iterate to do your work
for(String val:firstList) {
}
This is my function, to find a id from list by matching titles
public static int findIdByTitle(List<Integer> IDs, List<String> Titles ,String title){
for (int i = 0; i < IDs.size(); i++){
if (Titles.get(i).equals(title))
return IDs.get(i);
}
return 0;
}
This function search in model list and find id
But I can't use this because:
int id = findIdByTitle(Core.userSignIn.getBasicList().getGradeList().get(****?****).getID()
,Core.userSignIn.getBasicList().getGradeList().get(****?****).getName()
,spinnerGrade.getSelectedItem().toString());
I must give it a number position : ( see the lists.get(****?****).getID() or getName()
I want using that's function for all models not just for this model
give 2 lists and a matching word, use matching word to find position of that's in list, and give me a ID of this position
All of my model have ID , Title and some of them have ParentID
with help of Nitin , My problem has been resolved:
List<String> Titles = new ArrayList<>();
List<Integer> IDs = new ArrayList<>();
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
Titles = Core.userSignIn.getBasicList().getGradeList().stream().map(GradeList::getGradeName).collect(Collectors.toList());
IDs = Core.userSignIn.getBasicList().getGradeList().stream().map(GradeList::getGradeID).collect(Collectors.toList());
} else {
Titles = new ArrayList<>(Core.userSignIn.getBasicList().getGradeList().size());
IDs = new ArrayList<>(Core.userSignIn.getBasicList().getGradeList().size());
for (GradeList gradeList : Core.userSignIn.getBasicList().getGradeList()) {
Titles.add(gradeList.getGradeName());
IDs.add(gradeList.getGradeID());
}
}
educationList1.setiGradeID(findIdByTitle(IDs
,Titles
,spGrade.getSelectedItem().toString()));
You first have to convert your list to List of Integer and List of String and then pass it to your method. You can use below code if you are using Java 8:
final List<Integer> testList1 = BasicList().getGradeList().stream().map(Test::getId).collect(Collectors.toList());
final List<String> testList2 = BasicList().getGradeList().stream().map(Test::getName).collect(Collectors.toList());
Replace your class name in place of Test in above code.
Use below code for below java 8 env:
List<String> strings = new ArrayList<>(BasicList().getGradeList().size());
for (Test test : BasicList().getGradeList()) {
strings.add(test.getName());
}
Similar for Ids.
You need another loop if you want to get all Ids of your models, you can do something like this :
List<Integer> listId=new ArrayList<Integer>();
for(int i=0; i<BasicList().getGradeList().size(); i++) {
listId.add(findIdByTitle(BasicList().getGradeList().get(i).getID()
,BasicList().getGradeList().get(i).getName()
,spinnerGrade.getSelectedItem().toString()));
}
EDIT:
Sorry forr the misspellings and typos, I didn't want to put my code here so I tried to make a new look a like code to express my question.
Here is the actual code I'm using, I just removed some parts of it as they are not related to my question, I think, otherwise just ask me and I'll put it here as well.
Heres the actual code:
public class Dados {
private String sta;
private String ap;
private int startTime;
private int endTime;
private int repetitionSTA;
private int pingPong;
private int tt_previous;
private int tt_next;
private int id;
public Dados(int id, int startTime, int endTime, String ap, String sta, int repetitionSTA, int ttprevious, int ttnext, int ppong)
{
this.sta = sta;
this.ap = ap;
this.startTime = startTime;
this.endTime=endTime;
this.pingPong = ppong;
this.tt_next = ttnext;
this.tt_previous = ttprevious;
this.id = id;
this.repetitionSTA = repetitionSTA;
}
// SET
public void setPingPong()
{
this.pingPong = 1;
}
//GET
public int getPingPong()
{
return this.pingPong;
}
}
//another class from now on
public class Queries extends LigarBD{
String dbtime = null;
int id = 1;
TreeMap<Integer, ArrayList> tmValores = new TreeMap<>();
ArrayList<Dados> listaObjectos = new ArrayList<>();
ArrayList<Dados> listaObjectos2 = new ArrayList<>();
public ArrayList getUniqueStations(String server)
{
ArrayList<String> listaSTA = new ArrayList<>();
String query = "SELECT distinct calling_station_id FROM java_logs;";
try
{
super.ligar(server);
Statement s = super.getConexao().createStatement();
ResultSet rs = s.executeQuery(query);
while (rs.next())
{
listaSTA.add(rs.getString(1));
}
rs.close();
s.close();
super.desligar(super.getConexao());
}
catch (Exception e)
{
JOptionPane.showMessageDialog(null, "Error at listing all unique stations. Reason -> "+e.getMessage());
System.out.println("Error at listing all unique stations. Reason -> "+e.toString());
}
return listaSTA;
}
public ArrayList getStationData(String mac, String server)
{
try
{
super.ligar(server);
Statement s = getConexao().createStatement();
ResultSet rs = s.executeQuery("SELECT timestamp-acct_session_time, timestamp, called_station_id, calling_station_id "
+ "FROM java_logs where calling_station_id = '"+mac+"';"); // retirar STA da query *******************
//System.out.println("Executing the Query on+"+server+" - UniqueSTA - Query number: 1?");
int repetitionSTA=1;
while (rs.next())
{
Dados d = new Dados(id, rs.getInt(1), rs.getInt(2), rs.getString(3), rs.getString(4), repetitionSTA, 0, 0, 0);
listaObjectos2.add(d);
repetitionSTA++;
id++;
}
rs.close();
s.close();
super.desligar(super.getConexao());
}
catch (Exception e)
{
JOptionPane.showMessageDialog(null,"Error at Select Query. Reason -> "+e.getMessage());
}
return listaObjectos2;
}
}
Another class:
public class Pingpong {
ArrayList<Dados> dadosArray = new ArrayList<>();
Queries q = new Queries();
TreeMap<Integer, ArrayList> mapa = new TreeMap<>();
ArrayList<Dados> arrayDeDados = new ArrayList<>();
public ArrayList detectPingPongArray(int threshold_access_session_time, int threshold_transition_time, ArrayList<Dados> dadosSTA)
{
dadosArray=dadosSTA;
for(int i = 1; i<arrayDeDados.size()-1; i++)
{
dadosArray.get(i).setPingPong();
}
return dadosArray;
}
}
And here is where I'm printing each object one by one:
ArrayList<Dados> dadosSTA = new ArrayList<>();
ArrayList<Dados> dataForPPong = new ArrayList();
ArrayList uniqueSTA = q.getUniqueStations("localserver");
for(int i = 0; i<uniqueSTA.size(); i++)
{
dadosSTA = q.getStationData(uniqueSTA.get(i).toString(), "localserver");
dataForPPong = p.detectPingPongArray(5, 3, dadosSTA);
}
for(int i=0; i<dataForPPong.size(); i++)
{
System.out.println("ID: "+dataForPPong.get(i).getId()+" STA: "+dataForPPong.get(i).getStation()
+ " PingPong: "+dataForPPong.get(i).getPingPong());
}
So I was expecting it to change the value of pingPong in all objects to 1 but it doesn't.
I think the problem is with the returning from the method detectPingPongArray but I don't know where is the mistake.
Anyone can pinpoint the problem here?
The Problem
I'd say there are some bad practices in your code, such as disregarding the generics in ArrayLists, but let's get to the point.
It seems to me, that your problem is in the following method:
public ArrayList detectPingPongArray(
int threshold_access_session_time,
int threshold_transition_time,
ArrayList<Dados> dadosSTA
) {
dadosArray=dadosSTA;
for(int i = 1; i<arrayDeDados.size()-1; i++) {
dadosArray.get(i).setPingPong();
}
return dadosArray;
}
This is your code, just with a different formatting to fit in the answer.
The method receives an ArrayList<Dados> dadosSTA, which you assign to dadosArray.
You return this same variable, and you want to perform modifications on it.
However, you are iterating over arrayDeDados's size, which is a different ArrayList<Dados>, and, from what you give us, is also an empty list.
ArrayList<Dados> arrayDeDados = new ArrayList<>();
Thus, since the size() of an empty list is zero, no iterations are performed, and setPingPong() is never called.
Tips
As requested, I'm also adding some tips for the future.
Although not necessarily a bad practice, more of a personal preference, I wouldn't name my classes / variables in portuguese (which it seems to be in this case), or any language other than english. It keeps the code more readable for others, in situations such as this.
public class Queries extends LigarBD
I'm not sure that a class to perform queries on a database should extend a class that connects to a database. Instead, it would seem more appropriate to use a class that connects to the database.
This is easily seen by some patterns in your code, such as super.ligar(), super.getConexao(), super.desligar(), which you do in both methods you shared with us. You seem to be interested in using the interface provided by LigarBD, and not extend it, or add functionality to it. You could change this by declaring an instance variable of type LigarBD, and using it accordingly.
public ArrayList detectPingPongArray
Here, you throw away the generic information associated with the ArrayList.
If you know you'll be returning an ArrayList<Dados>, and you want the callers of this method to know that too, you should declare the method as follows:
public ArrayList<Dados> detectPingPongArray
This way, the callers will expect an ArrayList<Dados>, instead of an ArrayList of something (potentially introducing unsafe casts / operations).
Further Analysis
I'm also not sure if this is on purpose, but I've found something rather curious in your code.
ArrayList<Dados> dadosSTA = new ArrayList<>();
ArrayList<Dados> dataForPPong = new ArrayList();
ArrayList uniqueSTA = q.getUniqueStations("localserver");
for(int i = 0; i<uniqueSTA.size(); i++)
{
dadosSTA = q.getStationData(uniqueSTA.get(i).toString(), "localserver");
dataForPPong = p.detectPingPongArray(5, 3, dadosSTA);
}
for(int i=0; i<dataForPPong.size(); i++)
{
System.out.println("ID: "+dataForPPong.get(i).getId()+" STA: "+dataForPPong.get(i).getStation()
+ " PingPong: "+dataForPPong.get(i).getPingPong());
}
The first for loop just assigns new values to the variables, doing nothing with them and constantly overwriting them.
Probably, you want this loop to also include the second loop, so that you effectively print all values, for every ArrayList that is assigned to dataForPPong. Or you'll just add something else inside this loop in the future, but I wanted to point out that this may be a future source of bugs.
I need to join two Collection<String>, get n random elements and remove them from the original collection in which they are stored.
To join the collections I thought about iterate them and store in an custom map structure in a way to:
have the same key stored n times
get the original collection.
Is there a simple method to do that?
Can you help me?
How about this:
Collection<String> collection1 = new ArrayList<String>();
Collection<String> collection2 = new ArrayList<String>();
List<String> allElements = new ArrayList<String>(collection1);
allElements.addAll(collection2);
Collections.shuffle(allElements);
Random random = new Random();
int n = 10;
List<String> randomResults = new ArrayList<String>(n);
for (int i = 0; i < n && !allElements.isEmpty(); i++) {
String randomElement = allElements.remove(random.nextInt(allElements.size()));
randomResults.add(randomElement);
}
collection1.removeAll(randomResults);
collection2.removeAll(randomResults);
Interesting you want to use the map for that. I would suggest using a MultiMap (Google's Guava for example). It allows you to hold a key and then a Collection of values, all belonging to that key. So, you would have only two keys (corresponding to your original Collections).
Another solution would be to just add all Collections into a third a Collection (there is an addAll(Collection c) method available). Provided, there are no duplicate values, you can check if a certain item from the third collection is part of any of your other two while iterating.
These are kind of rudimentary ways to achieve whatever your question asked, but worth a try.
Hope these pointers help a bit!
Does the following work for you?
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Random;
import java.util.Set;
import com.google.common.collect.Iterables;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
public class Combiner {
private static final Random rnd = new Random();
public static void main(String[] args) {
Collection<String> boys = Sets.newHashSet("James", "John", "andrew",
"peter");
Collection<String> girls = Sets.newHashSet("mary", "jane", "rose",
"danny");
// Combine the two
Iterable<String> humans = Iterables.concat(boys, girls);
// Get n Random elements from the mix
int n = 2;
Collection<String> removed = randomSample4(humans, n);
// Remove from the original Collections
Iterables.removeAll(boys, removed);
Iterables.removeAll(girls, removed);
// or even
boys.removeAll(removed);
girls.removeAll(removed);
// And now we check if all is well
System.out.println(boys);
System.out.println(girls);
}
public static <T> Collection<T> randomSample4(Iterable<T> humans, int m) {
List<T> sample = Lists.newArrayList(humans);
Set<T> res = new HashSet<T>(m);
int n = sample.size();
for (int i = n - m; i < n; i++) {
int pos = rnd.nextInt(i + 1);
T item = sample.get(pos);
if (res.contains(item))
res.add(sample.get(i));
else
res.add(item);
}
return res;
}
}
The randomSample4 method has been copied from this blog.