I have an declared an ArrayList a = [1,2,3]. I created another ArrayLList b using the loop below:
for(int i = 0; i<a.size(); i++)
{
for(int j=i+1; j<a.size();j++)
{
b.add("{" + a.get(i)+ "," + a.get(j) + "}");
}
}
Now the ArrayList b will contain elements [{1,2},{1,3},{2,3}]. Now if I print the statement using System.out.println(b.get(0)), then the output will be {1,2}.
Now I want to to further explore the array such that I can extract 1 and 2 separately. How can I achieve this?
create class pair
class Pair{
String a
String b
....
///setters and getters
}
now let b will be List<Pair> so instead calling b.add("{" + a.get(i)+ "," + a.get(j) + "}"); you can do simple b.add(new Pair(a.get(i),a.get(j));
then you don't need to play with splitting string and stuff like that, you can easly access your values by doing ie b.get(0).getA() or b.get(0).get()
you can also override method to string in pair
public String toString() {
return "{" + a+ "," + b + "}";
}
so when you do System.out.println(a.get(0)) you will get exactly same output like before
***EDIT
if you want to have a groups of more than 2 elements as you say in comment
you can construct your class little bit different
class MyClass{
List<Integer> fields = new ArrayList<Integer>();
//two constructors
MyClass(int singleVal)
{
fields.add(singleVal);
}
MyClass(MyClass a, MyClass b)
{
fields.addAll(a.fields);
fields.addAll(b.fields);
}
//getters setters depends what you need
}
both of your list will be list of MyClass, when you populate list a, you create objects by using first constructor, when you want to add elements to your b list you can do b.add(new MyClass(a.(i),a.(j))) but you can also do b.add(new MyClass(a.(i),b.(j))) or b.add(new MyClass(b.(i),b.(j)))
I understand that your array b holds just strings. Use any String tokenizing mechanism to achieve this - either String.split or StringTokenizer
Hint : StringTokenizer performs better
You should decompose the presentation from logic.
In your loop you create a pair of element. So create a some type to represent it.
class Pair {
private int left;
private int right
Pair(int left, int right) {
this.left = left;
this.right = right;
}
public int getLeft() {
return this.left;
}
public int getRight() {
return this.right;
}
#Override
public void toString() {
return String.format("{%d , %d}",getLeft(),getRight());
}
}
List list = new ArrayList();
for(int i = 0; i<a.size(); i++)
{
for(int j=i+1; j<a.size();j++)
{
list.add(new Pair(i,j));
}
}
Then to access (extract) items
int l = list.get(0).getLeft();
int r = list.get(0).getRith();
If you want to display on console the result.
for(Pair p : list) {
System.out.println(p);
}
About output format
EDIT
AS the OP mentioned in the comment. He would like to have flexible data structure that allow him to store the data.
List<List<Integer> parent = new ArrayList<List<Integer>()
for(int i = 0; i<a.size(); i++)
{
List<Integer> child = new ArrayList<Integer>();
for(int j=i+1; j<a.size();j++)
{
child.add(a.get(i));
child.add(a.get(j));
}
parent.add(child);
}
String ele = b.get(0);
ele = ele.replace("{", "");
ele = ele.replace("}", "");
StringTokenizer tokens = new StringTokenizer(ele, ",");
while(tokens.hasMoreTokens()) {
int val = Integer.parseInt(tokens.nextToken());
}
Related
There is a list of 200 students names and exam results.
My task is: "Create a constructor method for this list and put them in descending order with for statement".
I've done the first part. I can print out the list also. But I have no idea how to put them in descending order using for statement. Can anyone show me how to do that?
Current code:
package training;
public class ExamResult {
String studentName;
String examName;
int points;
String date;
ExamResult(String studentName, String examName, String date,int points) {
this.studentName=studentName;
this.examName=examName;
this.points=points;
this.date=date;
}
public void display() {
System.out.println(studentName + " " + examName + " " + date + " " + points);
}
}
package training;
public class DisplayExamResults {
public static void main (String args[]) {
ExamResult one=new ExamResult("Ryan Pena","Sociology","21/06/2016",16);
ExamResult two=new ExamResult("Portia Hamilton","Sociology","21/06/2016",34);
ExamResult three=new ExamResult("Ryan Pena","Sociology","21/06/2016",35);
one.display();
two.display();
three.display();
}
}
So, Daniel! This is going to be long because you are new to Java and I will try to explain everything. You can always read more about a lot of things here but I will explain just enough for this problem.
When you want to sort objects of a class, in your case, class ExamResult, you cannot just use a for loop on one of the fields and finish sorting. In order to achieve your desired sorting, you will need to use an interface called Comparable. This interface lets you write your own sorting criteria based on the structure of your class.
We will proceed step by step.
Step 1: Implement the Comparable interface in the ExamResult class
Since you want to sort objects of the ExamResult class, this is where you will implement the interface. By that, we mean, you will write how you want to sort your objects. We want to sort based on the student names. And for sorting, we will need to compare objects to see which one is greater than the other.
Here, we will use a term called overriding which basically means that we will override the comparison function which was declared in the Comparable interface.
Our definition below takes as input an object of the class ExamResult and compares its student name with that of the current object - this. On comparison, it returns an integer:
0, if the names are equal
>0, if the other object's student name is greater than the current one
<0, if the other object's student name is lesser than the current one
package training;
public class ExamResult implements Comparable<ExamResult> {
/* your previous code remains here as is*/
// this function returns the name of the student
public String getStudentName() { return studentName; }
#Override
// write your sorting criteria
public int compareTo(ExamResult other) {
String name1 = this.getStudentName();
String name2 = other.getStudentName();
return name1.compareTo(name2);
}
}
Step 2: Construct a list of ExamResult objects in DisplayExamResults class
Now that we have finished defining how to compare objects, we need a list of those objects on which we will run the for loop and perform the comparison.
We can do that in the DisplayExamResults class like so:
// Create a list of results on which you will run your for loop
List<ExamResult> resultList = new ArrayList<>();
resultList.add(one);
resultList.add(two);
resultList.add(three);
Here, the List interface lets you define a list of objects of any user defined class like yours. So you create a list and add the ExamResult objects to it.
Step 3: Sort using the for loop
This is the final step, where you perform the actual sorting in the DisplayExamResults class. We will first sort in ascending order and then reverse the list.
You start with a left (i) and a right (j) pointer. i is set to 0 because it starts at the beginning of the list and j is set at the end of the list.
As you keep comparing, if the object on the left is smaller than the one on the right, you just move on, i.e. increment i. Similarly, if the object on the right is greater than that on the left, just move on by decrementing j.
But, if the order is not like that, then you swap them. Which is what we do in the if statement. You can see that we are using the compareTo() function that we had defined above.
// Loop over that list to sort the objects
for (int i = 0; i < resultList.size(); i++) {
for (int j = resultList.size() - 1; j > i; j--) {
if (resultList.get(i).compareTo(resultList.get(j)) > 0) {
ExamResult temp = resultList.get(i);
resultList.set(i, resultList.get(j));
resultList.set(j, temp);
}
}
}
// For descending order
Collections.reverse(resultList);
// Display the results after sorting is over
for (ExamResult r : resultList) {
r.display();
}
Phew! Now, we put all that code together to get the following two files.
package training;
public class ExamResult implements Comparable<ExamResult> {
String studentName;
String examName;
int points;
String date;
ExamResult(String studentName, String examName, String date,int points) {
this.studentName=studentName;
this.examName=examName;
this.points=points;
this.date=date;
}
public void display() {
System.out.println(studentName + " " + examName + " " + date + " " + points);
}
// this function returns the name of the student
public String getStudentName() { return studentName; }
#Override
// write your sorting criteria
public int compareTo(ExamResult other) {
String name1 = this.getStudentName();
String name2 = other.getStudentName();
return name1.compareTo(name2);
}
}
And
package training;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class DisplayExamResults {
public static void main (String args[]) {
ExamResult one = new ExamResult("Ryan Pena","Sociology","21/06/2016",16);
ExamResult two = new ExamResult("Portia Hamilton","Sociology","21/06/2016",34);
ExamResult three = new ExamResult("Ryan Pena","Sociology","21/06/2016",35);
one.display();
two.display();
three.display();
System.out.println("\n");
// Create a list of results on which you will run your for loop
List<ExamResult> resultList = new ArrayList<>();
resultList.add(one);
resultList.add(two);
resultList.add(three);
// Loop over that list to sort the objects
for (int i = 0; i < resultList.size(); i++) {
for (int j = resultList.size() - 1; j > i; j--) {
if (resultList.get(i).compareTo(resultList.get(j)) > 0) {
ExamResult temp = resultList.get(i);
resultList.set(i, resultList.get(j));
resultList.set(j, temp);
}
}
}
// For descending order
Collections.reverse(resultList);
// Display the results after sorting is over
for (ExamResult r : resultList) {
r.display();
}
}
}
I tried to explain the bits in there. Please read more and understand better. Hope it helps.
If the names are as a String Array or a List:
Using standard Java libraries:
String[] students = {"Aaron", "Jonas", "Bob", "Karl"};
Arrays.sort(students);
List<String> temp = new ArrayList<>(Arrays.asList(students));
Collections.reverse(temp);
temp.toArray(students);
OR
Using Bubblesort and chars to compare the strings:
String[] students = {"Aaron", "Jonas", "Bob", "Karl"};
char[] temp1;
char[] temp2;
int length;
for(int i = 0; i < students.length; i++){
temp1 = students[i].toLowerCase().toCharArray();
for(int n = i+1; n < students.length; n++){
temp2 = students[n].toLowerCase().toCharArray();
if(temp1.length > temp2.length)
length = temp2.length;
else
length = temp1.length;
for(int c = 0; c < length; c++){
if(temp1[c] < temp2[c]){
String temp = students[i];
students[i] = students[n];
students[n] = temp;
temp1 = students[i].toLowerCase().toCharArray();
break;
}
else if(temp1[c] > temp2[c])
break;
}
}
}
I'm taking a binary String like this:
010010010000110100001010
as a String, converting it to Integer Array like this:
int[] DD = new DD[binString.length()];
char temp = binString.charAt(i);
int binData = Character.getNumericValue(temp);
DD[i] = binData;
and I'm tying to save these Integer values in to HashMap(I have to store into a HashMap as per instructions given to me) like this:
Map<String, Integer> toMemory = new HashMap<String, Integer>();
for(int i=0;i<binString.length();i++) {
char temp = binString.charAt(i);
int binData = Character.getNumericValue(temp);
DD[i] = binData;
if((DD[i] & (DD[i]-1) ) == 0) {
toMemory.put(new String("ON"), new Integer(DD[i]));
} else {
toMemory.put(new String("ON"), new Integer(DD[i]));
}
}
for(String s: toMemory.keySet()) {
if(s.startsWith("ON")) {
System.out.println(toMemory.get(s));
}
}
The issue I'm facing here is that, only one entry is being stored in the HashMap, say {"ON",0}. And no other values are being stored. My expected output is this:
{"ON" , 1 , "OFF" , 0, "ON" , 1 .........}
Is there any better way to store the values to get my expected output? Any help will be much appreciated.
P.S: Please ignore the recurring code, and I'm relatively new to programming.
Your usage of a Map is flawed. Maps take a unique key and return a value.
You are trying to use duplicate keys. Instead, look at using a List with a wrapper class:
class ClassName {
public String status;
public int value;
public ClassName(String status, int value){
this.status = status;
this.value = value;
}
}
List<ClassName> list = new ArrayList();
To add to the list, create a new instance of your class and call List#add:
list.add(new ClassName("ON", 1));
as Infuzed Guy said, you are using the Map the wrong way. It's a unique "key to value mapping".
As long as you are using several times the same key and want to store all the dada, you need to use a List.
Here is what I could come up with the little you gave us: test it here
import java.util.LinkedList;
import java.util.List;
class Main {
public static void main(String[] args) {
class Tuple<X, Y> { //The wrapper object
public final X x;
public final Y y;
public Tuple(X x, Y y) { //Object constructor
this.x = x;
this.y = y;
}
public String toString() //Here for printing purpose
{
return "\"" + this.x + "\", " + this.y;
}
}
//Note here te use of List
List<Tuple> toMemory = new LinkedList<>();
String binString = "10100100101100101011";
int[] DD = new int[binString.length()];
for(int i=0; i < binString.length(); ++i)
{
//Here I use the char value
//to get the by subtraction
DD[i] = binString.charAt(i) - '0';
if(DD[i] == 1) //Simple check with the int value
{
toMemory.add(new Tuple<>("ON", DD[i]));
}
else
{
toMemory.add(new Tuple<>("OFF", DD[i]));
}
}
//Print the List
System.out.print("{ ");
for(Tuple s: toMemory) {
System.out.print(s +", ");
}
System.out.println("}");
}
}
i have a situation where i have to read xml files where i get three elements like this
2019-03-19,null,null
2016-11-30,null,null
2016-10-14,null,null
2016-09-30,null,null
2016-09-30,1,YEARS
2016-09-30,3,MONTHS
2016-09-30,4,MONTHS
I have to store all three items on some data structure and apply my logic like below
I have to find the max of last item and then for that i have to find the max of second item then for that i have to find the max of first element of more than one is present .
Please suggest me some idea
Create a single object like below that can hold all three data elements and is also capable of handling a "null" value for the quantity and term length values. You may want to have the constructor convert the String date (2019-03-19) into a real date object or you could handle that before object creation. Then add these objects to a data structure (i.e. list, etc) that you can use to manage and organize them.
public class ListElement {
public Date date;
public Integer qty;
public String termLength;
public ListElement(Date d, Integer q, String t) {
this.date = d;
this.qty = q;
this.termLength = t
}
// getter methods
public Date getDate() {
return this.date;
}
public Integer getQty() {
return this.qty;
}
public String getTermLength() {
return this.termLength;
}
public toString() {
return System.out.println(this.date + "::" +
this.qty + "::" +
this.termLength)
}
}
You can create an enum if you have some predefined terms:
enum Term {
AGES, YEARS, MONTHS, WEEKS, DAYS, HOURS, MINUTES, SECONDS;
}
And use it in your class with other two types as:
public class MyObjects {
private Date date;
private Integer quantity;
private Term term;
public MyObjects(Date date, Integer quantity, Term term) {
this.date = date;
this.quantity = quantity;
this.term = term;
}
// getters, setters
}
Then define the constructor that accepts these 3 arguments and use it while processing XML file.
Two different ways to store the data. One is 2D array and the other is arraylist. All the data is type String. You would have to Parse the Integers using Integer.parseInt() to get int value. You will also have to catch for null values. This assumes that your xml data have newline characters at the end of each line.
public static void main(String[] args) {
// TODO code application logic here
//Assuming there are \n char at end of line
String xml = "2019-03-19,null,null\n" +
"2016-11-30,null,null\n" +
"2016-10-14,null,null\n" +
"2016-09-30,null,null\n" +
"2016-09-30,1,YEARS\n" +
"2016-09-30,3,MONTHS\n" +
"2016-09-30,4,MONTHS";
System.out.println("2D Array Output:");
String[][] twoDArrayExample = twoDArrayVersion(xml);
//print 2D array
for(int i = 0; i < twoDArrayExample.length; i++)
{
for(int z = 0; z < twoDArrayExample[i].length; z++)
{
System.out.print(twoDArrayExample[i][z] + " - ");
}
System.out.println();
}
System.out.println("\n\nArray List Output:");
ArrayList<ArrayList<String>> arrayListExample = arrayListVersion(xml);
//print arraylist
for(ArrayList<String> entry : arrayListExample)
{
for(String item : entry)
{
System.out.print(item + " + ");
}
System.out.println();
}
}//end of main
static String[][] twoDArrayVersion(String xml)
{
String[][] dataHolder;
String[] tempDataHolder = xml.split("\n");
dataHolder = new String[tempDataHolder.length][3];
for(int i = 0; i < tempDataHolder.length; i++)
{
String[] tempDataHolder2 = tempDataHolder[i].split(",");
dataHolder[i][0] = tempDataHolder2[0];
dataHolder[i][1] = tempDataHolder2[1];
dataHolder[i][2] = tempDataHolder2[2];
}
return dataHolder;
}
static ArrayList<ArrayList<String>> arrayListVersion(String xml)
{
ArrayList<ArrayList<String>> dataHolder = new ArrayList();
String[] tempDataHolder = xml.split("\n");
for(int i = 0; i < tempDataHolder.length; i++)
{
ArrayList<String> tempArrayList = new ArrayList();
String[] tempDataHolder2 = tempDataHolder[i].split(",");
tempArrayList.add(tempDataHolder2[0]);
tempArrayList.add(tempDataHolder2[1]);
tempArrayList.add(tempDataHolder2[2]);
dataHolder.add(tempArrayList);
}
return dataHolder;
}
I am attempting to print out a hashset taking in records from a database which are currently stored in two seperate ArrayLists. When I attempt to print out the HashSet the following error shows.
This is your HashSet[nyu.Sorting#378bf509, nyu.Sorting#7b23ec81, nyu.Sorting#15aeb7ab, nyu.Sorting#27d6c5e0, nyu.Sorting#7ef20235, nyu.Sorting#4f3f5b24, nyu.Sorting#6acbcfc0, nyu.Sorting#2d98a335, nyu.Sorting#5fd0d5ae, nyu.Sorting#16b98e56]
And this is my code:
public static HashSet<Sorting> t() {
Sorting s = new Sorting();
int TimeNeededOne = 75;
int TimeNeededTwo = 75;
int assignedTimeOne = 0;
int assignedTimeTwo = 0;
HashSet<Sorting> c = new HashSet<Sorting>();
for(int i=0; i<=i1.size()-1; i++)
{
if((assignedTimeOne < TimeNeededOne) && !(assignedTimeOne+ i1.get(i).getLengthMins() > offensiveTimeInMins) )
{
c.add(i1.get(i));
assignedTimeOne += i1.get(i).getLengthMins();
}
}
for(int i=0; i<=i2.size()-1; i++)
{
if((assignedTimeTwo < TimeNeededTwo) && !(assignedTimeTwo + i2.get(i).getLengthMins() > TimeNeededTwo) )
{
c.add(i2.get(i));
assignedTimeTwo += i2.get(i).getLengthMins();
}
}
System.out.println("Training programme :" + c.size());
System.out.println("This is your training programme" + c.toString());
return c;
}
The c.size is there to confirm that ten entries are made which is correct however the formatting of the records from the hashset obviously contains a problem. Any help with this issue would be greatly appreciated.
Thanks.
One way of doing this would be to override the toString() method of your Sorting class to print its contents:
public class Sorting {
...
#Override
public String toString() {
// Return a String that represents this object
return "...";
}
}
You need override toString() method in the Sorting class, for example:
class Sorting {
...
#Override
public String toString() {
// a string representation of Sorting object
}
}
java.util.Iterator runs through the whole collection and for each element invokes a toString() method. The data recorded in the java.lang.StringBuilder, which returns of its string representation at the end.
so I'm implementing an ADT into this Linked List implementation and I need to use constructor chaining which makes my number into a String. Then I have to break it up into separate characters and store them in a a Linked List.
Note: I am using a wrapper class called Node
public class Node {
String item;
Node next;
public Node(String item, Node next) {
this.item=item;
this.next=next;
}
}
This is my code so far for trying to split up the String
public class LinkBNum implements BNum {
Node myList;
public LinkBNum() {
this(0);
}
public LinkBNum(long a) {
this(String.valueOf(a));
}
public LinkBNum(String s) {
for(int i=0; i<s.length(); i++) {
myList = new Node(s.charAt(i),null);
}
}
How would accomplish splitting my string up and placing it into a Linked List?
You can use s.toCharArray() function to get the individual characters in a character array
String numAsStr = (new Integer(num)).toString();
int[] digits = new int[numAsStr.length()];
for(int i = 0; i < digits.length; i++) {
digits[i] = Character.getNumericValue(numAsStr.charAt(i));
}
I just typed this on a 3-inch screen, so forgive a few typos. :)
try this:
public LinkBNum(String s) {
for(char c : s.toCharArray()) {
if (null == myList)
myList = new Node(c,null);
else
myList.next = new Node(c,null);//assuming 'next' is accessible here
}
}
Try this
public LinkBNum(String s) {
while (s.length()>0) {
myList = new Node(s.substring(0, 1),null);
s=s.substring(1)
}