I have an object array containing two fields per object.
I have to write a method that will sort my array by the first field.
I already have a method which extracts the first field from each object
I always get an error message when I call my method to sort.
Here is my code:
public static void trier(String[]code, String[]nom, int nbObj) {
for(int i = 0; i < nbObj-1; i++) {
int indMin = i;
for (int j = i+1; j < nbObj; j++)
if (code[j].compareTo(code[indMin]) < 0)
indMin = j;
if (indMin != i) {
// permutation :
String tempo = code[i];
code[i] = code[indMin];
code[indMin] = tempo;
// permutation :
String temp = nom[i];
nom[i] = nom[indMin];
nom[indMin] = temp;
}
}
}
and the call :
Classe.trier(tableau, tableau, nbObj);
I also tried Class.sort(array.getCode(), array.getName(), nbStudent);
But I still have compilation errors
thank you in advance for your help
First of all, you don't have to use 2 separate arrays to contain your data. You can put everything in a single array, but better way is to use Java Collections. Perfect choice is ArrayList. However, you still better combine two fields into a single object. You can do it like this:
public class MyObject {
String code;
String nom;
MyObject(String code, String nom) {
this.code = code;
this.nom = nom;
}
}
Now you have a class containing 2 fields. Your aim is to sort a collection of such objects by their second field (nom). You can do this easily since Java 8:
public static void sort1(ArrayList<MyObject> list) {
list.sort((obj1, obj2) -> obj1.nom.compareTo(obj2.nom));
}
Or
public static void sort2(ArrayList<MyObject> list) {
list.sort(Comparator.comparing(MyObject::getNom));
} // However for this you need to add method getNom to MyObject
Remember to put your objects in the collection properly.
For example:
MyObject a = new MyObject("abc", "abide");
MyObject b = new MyObject("cab", "whatever you want");
ArrayList<MyObject> list = new ArrayList<>();
list.add(a);
list.add(b);
trier(list);
Related
I am initalizing several objects of the same type that have a common field:
public class Example {
private static objectCounter = 1;
public Example () {
objectCounter++;
}
}
Since these objects are created with a for loop like this
for (int i = 0; i<5; i++) {
Example e = new Example();
}
they are not referenced.
Is there a way to get a specific object based on objectCounter value ?
Something like
//get the Example object with objectCounter==2
get(2);
Thank you
My suggestion will be saving into array:
Example store[] = new Example[5]
for (int i = 0; i<5; i++) {
store[i] = new Example();
}
And then , search for the specific object.
As stated in the comments, a static value will persist through all instances of your class.
If you want your Example to "know" it's identity, pass it in when you construct it:
Example:
public class Example {
private int id;
public Example (int val) {
this.id = val;
}
// Getters/setters
}
Probably also want to add your objects to a list to access them later, so before your for-loop:
List<Example> examples = new ArrayList()<Example>;
And create them like this:
for (int i = 0; i<5; i++) {
Example e = new Example(i);
examples.add(e);
}
I'm not understanding something, obviously. I've got a primitive array of ints, and I need to convert that into an array of my own type. Here's what I've tried.
public class StupidInt {
#JsonProperty("ID")
private int id;
public StupidInt(int id) { this.id = id; }
public int getId() { return this.id; }
}
public static void main(String []args){
int[] ints = {1,2,4,67};
StupidInt[] myInts = IntStream.of(ints).map(StupidInt::new).collect(Collectors.toList());
}
As you might expect, myInts line has a problem and that problem is "cannot convert StupidInt to int". But I'm not sure what combination of map or foreach or whatever intermediate and terminal methods to use to convert that array of ints to an array of my object. What is the correct way to do this conversion?
You need to use mapToObj to create a new Stream of objects and toArray instead of collect to obtain the result as an array.
StupidInt[] myInts = IntStream.of(ints).mapToObj(StupidInt::new).toArray(StupidInt[]::new);
The answer from #hev1 is simple and the best answer for a terminal method for what you are trying to achieve.
I provide here two different options if you need a different solution. The first is just a for intermediate method to create the primitive array; and the second option is a wholesome different approach to the problem and does not create a primitive array but a "list" of the type Object that reflect the primitive type and will also work with any type or object:
Solution 1:
int[] ints = {1,2,4,67};
StupidInt[] myInts = new StupidInt[ints.length];
for (int i = 0; i < myInts.length; i++) {
myInts[i] = new StupidInt(ints[i]);
}
Solution 2:
public class StupidIntList {
private ArrayList<Integer> ids;
public StupidIntList() {
this.ids = new ArrayList<Integer>();
}
public void add(int id) {
this.ids.add(id);
}
public int get(int pos) {
return this.ids.get(pos);
}
public boolean findId(int i_d) {
for (Integer id : ids) {
if(id == i_d)
return true;
}
return false;
}
public String toString() {
String res = "[";
for (Integer id : ids) {
res += id+",";
}
return res.substring(0, res.lastIndexOf(","))+"]";
}
public static void main(String []args){
int[] ints = {1,2,4,67};
StupidIntList myInts = new StupidIntList();
for (int i = 0; i < ints.length; i++) {
myInts.add(ints[i]);
}
System.out.println(myInts);
}
}
In this case to add a new int you use the add method and to get one int you will use the get(position) method or the find method to look if it exists and get the position.
Or you could simply use the ArrayList class or if you want I can share with you a list structure that allows what you need to accomplish, has most methods you can think of, implements comparable, can be ordered, implements iterable and is very efficient.
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.
Hello I have implemented this basic program which should sort out the strings that are inserted however it somehow is failing to insert the strings .
For example if I implement :
TestSort t = new TestSort();
t.i("abc");
t.i("aab");
Can anybody see the error and help me fix this error please ?
Thank you
Here is the code :
public class TestSort {
private int length;
String[] data;
public TestSort() {
length = 0;
}
public void i(String value) {
data[length] = value;
setSorted(data);
length++;
}
public void setSorted(String data[]) {
for(int i = data.length-1; i >= 0; i--) {
for(int j = 0; j < i; j++) {
if(data[j].compareTo(data[j + 1]) > -1) {
String temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
}
for(int i = 0; i < data.length; i++) {
System.out.print(data[i] +" ");
}
}
}
You don't initialize the array data. So it is set null, and accesses with data[i] will get you an NullPointerException. Even if you initialize this field, it will not work, as Arrays in Java have a fixed size, you have to reallocate the Array, if you insert a new value. You should try a List-implementation instead.
So the code should initialize in the constructor:
data = new ArrayList<String>();
and insertion would change to
data.add(value);
you can change your constructor code as (String array max length can be taken as input parameter):
public testsort()
{
data = new String[10];
length = 0;
}
But if you are not sure with the size of array you can use ArrayList.
You are getting exception because you are comparing with data[j+1] that is still null.
first time when you call
t.i("abc");
there is only one reference in data array that is pointing to String literal "abc" and that is at index 0. index 1 is still referring to null.
first String is already sorted so no need to sort that. if you are having more than one string then you should call setSorted() method.
to solve this you can put your condition in loop as:
if((data[j] != null && data[j+1] != null) &&(data[j].compareTo(data[j + 1]) > -1))
A working example but still: use a List and life is much easier :-)
public class Test {
private int length;
private String[] data;
public Test(int arrayLength) {
// INITIALIZE YOU ARRAY --> No NULLPOINTEREXCEPTION!
data = new String[arrayLength];
length = 0;
}
public void i(String value) {
data[length] = value;
length++;
}
public void setSorted() {
for (int j = 0; j < data.length - 1; j++) {
if (data[j].compareTo(data[j + 1]) > -1) {
String temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
for (String s : data) {
System.out.println(s);
}
}
public static void main(String[] args) {
Test t = new Test(5);
t.i("bbb");
t.i("aaa");
t.i("ccc");
t.i("zzz");
t.i("ddd");
// USE SETSORTED HERE --> else you fill your array with the same elements
t.setSorted();
}
}
The variable 'data' is null since it is nowhere initialized hence giving null pointer exception. Since 'data' is an array and as per the rule whenever an array is defined, it has to be of defined length. for e.g if we consider your case. 'data' can be initialized as :-
String[] data = new String[any numerical value]
the numerical value will be its length i.e. the maximum number of elements it can hold.
Secondly, as per your program statement :-
data[length] = value;
is trying to assign value at data's [length] index which is completely wrong since you haven't defined the length therefore how could you guess the index's value. Therefore your this approaoch is logically wrong.
For such situation i.e. whenever we're unaware about the length of the array, use of ArrayList is suggested. Therefore your program can be re-written by two ways:-
1) Either define the length of the array
String[] data = new String[n];
where n ranges from at least 1 to any positive integer.
2) By using ArrayList
public class Main {
List<String> data;
public Main(){
data = new ArrayList<String>();
}
public static void main(String... q){
Main m = new Main();
m.insertData("abc");
m.insertData("zxy");
m.insertData("aab");
m.insertData("aaa");
m.showData();
}
public void insertData(String str){
data.add(str);
Collections.sort(data);
}
public void showData(){
if(data!=null && !data.isEmpty()){
for(String s : data){
System.out.println(s);
}
}
}
}
output:-
aaa
aab
abc
zxy
Hope this helps.
as Mnementh suggested, the reason for NPE is that you have created the field data of type String[] but you never initialized it.
Other answers have provided every reason on why your code throwing ugly errors; I have just improved your code by replacing your String[] with List<String> so you don't have to worry about the size of your array anymore.
Sorting is also simplified now using Collections.sort().
have a look,
class test1 {
public static void main(String[] args) {
Test sorting = new Test();
sorting.input("abc");
sorting.input("cba");
sorting.input("aab");
sorting.setSorted();
}
}
class Test {
private List<String> data = new ArrayList<String>();
public void input(String value) {data.add(value);}
public void setSorted() {
Collections.sort(data);
for (String current : data) {
System.out.println(current);
}
}
}
if you are using Java 8, then you can use Arrays.parallerSort(), it performs sorting the same way as Collection.sort but with a parallel implementation.
Current sorting implementations provided by the Java Collections Framework > (Collections.sort and Arrays.sort) all perform the
sorting operation sequentially in the calling thread. This enhancement
will offer the same set of sorting operations currently provided by
the Arrays class, but with a parallel implementation that utilizes the
Fork/Join framework. These new API's are still synchronous with regard
to the calling thread as it will not proceed past the sorting
operation until the parallel sort is complete.
to implement it, replace Collections.sort with Arrays.parallelSort in the above code,
Replace,
Collections.sort(data);
with,
Arrays.parallelSort(data.toArray(new String[data.size()]));
I have an arrayList which contains Objects. Each object contains a number of strings. I am trying to take these strings and add them to a two dimensional array.
public void iterateRow(Row row)
{
int x = 0;
int y = size();
tableArray = new String[y][5];
while(x < y){
int z = 0;
for (String s: row.rowString()){
tableArray[x][z] = s;
z++;
}
x++;
}
}
Whenever i run and create a new instance for the row class the method should add the strings contained in Row to the array. However it duplicates the latest entry x times (where x is the total number of entries).
Here is the Row class for further reference:
public class Row
{
public String appNumber;
public String name;
public String date;
public String fileLoc;
public String country;
public String elementString;
public String results[];
public Row(String appNumber, String name, String date, String fileLoc, String country, Table table)
{
this.appNumber = appNumber;
this.name = name;
this.date = date;
this.fileLoc = fileLoc;
this.country = country;
table.addApplicant(this);
}
public String[] rowString()
{
String[] a = {appNumber, name, date, fileLoc, country};
return a;
}}
I think it is a silly logical error in the iterateRow() method but i can't seem to work out what. Any help would be appreciated.
Edit: After everybody's help i have removed the while loop. However it still seems to be duplicating the Row rather than moving onto the next?
public void iterateRow(Row row)
{ int x = 0;
int y = size();
tableArray = new String[y][row.rowString().length];
for(int i =0; i<y;i++){
int z = 0;
for (String s: row.rowString()){
tableArray[x][z] = s;
z++;
}x++;}
}
The problem looks like it is in the while loop. If size() returns 3, for example, then the while loop will execute with x=0,1,2 so you'll assign tableArray[0], then tableArray[1] and then tableArray[2].
Its hard to tell what the solution is as I can't understand why you've got the while loop in the code at all.
It looks like you want to iterate through each element of a List of Rows
Maybe you want to use a method similar to the following:
public void iterateRows(List<Row> rows) {
int cols = 5;
int row = 0, col = 0;
tableArray = new String[rows.size()][cols];
for(Row row : rows) {
col = 0;
for(String c : row.rowString()) {
tableArray[row][col] = c;
col++;
}
row++:
}
}
However, it would be good to implement your own error checking incase there are more than 5 columns...
EDIT
This is probably not the best design to use for your program, and I would recommend changing it so that when a new row is added, you don't have to iterate through each of the old rows as well.
Your iterateRow method re-creates tableArray each time it is called. Because of the while loop, your Row object gets replicated y times in the array.
I suspect that you want to create your array outside of the iterateRow method and not use a while loop (just the for loop) to populate the next slot in your array.
You are not taking care to size the two dimensional array relative to the size of the Row.
While this might not be the smoking gun, it would be far safer to do
tableArray = new String[y][row.rowString().length];
instead of
tableArray = new String[y][5];
I don't know if this is for practical purpose or how IterateRow() is called, but a logical way to get this working would be to declare the array first, add 2 argument in IterateRow(reference of the array and currentRow). Then, inside iterateRow you get rid of the while loop and you just loop for the string proprieties.