I have the following code snippets and would like to know how 'this' is being used as well as if there is another way of doing it with same end result. I tried generating an ArrayList by doing, ArrayList a = new ArrayList();, but it did not include the numbers '1, 2' and only have '4,6'. The output should be '1, 2, 4, 6'.
I am highlighting the code I am asking about:
int i = 0;
Sequence a = this;
Methods:
import java.util.ArrayList;
public class Sequence
{
private ArrayList<Integer> values;
public Sequence()
{
values = new ArrayList<Integer>();
}
public void add(int n)
{
values.add(n);
}
public String toString()
{
return values.toString();
}
public Sequence append(Sequence other)
{
int i = 0;
Sequence a = this;
while(i < other.values.size())
{
a.add(other.values.get(i));
i++;
}
return a;
}
}
Tester/Driver:
public class SequenceTester
{
public static void main(String[] args)
{
Sequence obj2 = new Sequence();
obj2.add(4);
obj2.add(6);
Sequence obj = new Sequence();
obj.add(1);
obj.add(2);
Sequence append = obj.append(obj2);
System.out.println(append);
}
}
would like to know how 'this' is being used
"this" refers to the current instance of a class.
if there is another way of doing it with same end result.
There is no need to explicitly create a Sequence variable in the append(...) method.
You can just invoke the add(...) method directly and return "this":
public Sequence append(Sequence other)
{
int i = 0;
//Sequence a = this;
while(i < other.values.size())
{
//a.add(other.values.get(i));
add(other.values.get(i));
i++;
}
// return a;
return this;
}
Methods of the class always operate on the current instance of the class so there is no need to use "this" to get a reference to the class.
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);
I was trying to construct a simple list class using generics.
However, it throws classcastexception when I was trying to print out the value. Is there any problem when I declare and initialize generic array?
class vector<E> {
static int MAX_LEN = 1234567;
E[] data;
int[] prv;
int to;
int size;
vector() {
data = (E[])new Object[MAX_LEN];
prv = new int[MAX_LEN];
to = -1;
size = 0;
for(int i = 0; i < MAX_LEN; ++i) {
prv[i] = -1;
}
}
void push_back(E e) {
data[size] = e;
prv[size] = to;
to = size;
++size;
}
}
public class Main {
public static void main(String[] args) throws Exception {
vector<Integer> v = new vector();
v.push_back(1);
v.push_back(2);
v.push_back(3);
v.push_back(4);
v.push_back(5);
for(int i = v.to; i != -1; i = v.prv[i]) {
System.out.println(v.data[i]); //<- Exception here
}
}
}
There are a few things wrong with the code.
It looks like, you've missed a <> in the line vector<Integer> v = new vector();
A cast from Object[] to Integer[] will never succeed
Ex:
Integer[] a= (Integer[]) new Object[] {}; // this cast will never succeed
Infact you can only cast Object[] to Object or Object[].
currently when you are trying to access data in the main() method, the cast put in by the compiler for you Integer[] will fail at runtime. You don't need the data array, you just need the values from it, which you can get by adding the following method to the vector class.
E getData(int index) {
return data[index];
}
In this case, compiler will add the cast to individual elements and will provide you the correct values.
You really have two options here. Either use data array of Object[] type or create proper generic array. Here is how to create generic array.
vector(Class<E> clazz) {
data = (E[])Array.newInstance(clazz, MAX_LEN);
Is there a way for objects inside an array to detect what slot they are in? If I had a Object array, could a Object inside the array detect what cell it is in without being explicitly told?
Nope, unfortunately, how arrays work in Java is that the array simply "points" to an object. As a Java array only stores references (to objects), but any number of variables can reference the same object, so an Object has no idea where it lives in an array. In fact, the same object can be pointed to from several indices in the array!
Consider
Object o = new Object(); // The variable o has a "reference" to the Object in memory
Object[] arr = new Object[3]; // empty array to hold Object types
arr[0] = o; // the first index points to the Object we created above
arr[1] = o; // the second index points to that same object!
arr[2] = o; // still the same object! If we modified the original object (assuming it's not immutable) in any way, all the indices in this array would point to the modified object.
Hope this helps!
The fastest (easiest to write) way to iterate through an array of objects is
for (Object o : arr) {
// do something to the local variable o, which you can think of as representing each object in your array
}
No. If you need to do this, you probably have a design flaw. Why does an Object need to know where it appears in the array? If the index is of some semantic meaning or interest to the object, then the object should have an int field containing this information. If you are trying to modify the original array based on one object then you probably have a poorly-factored class somewhere, e.g. if something such as this is happening:
class A {
Object data[];
}
class B {
remove(A a, Object instance) {
// how to remove instance from a.data??
}
}
Then really B.remove should be a method of A and hence have access to data in the first place. And so forth.
Furthermore an array may just not be the right data structure. If the index has much semantic value a Map<Integer, Object> may be more appropriate, although arrays are often used to represent this when the indices are continuous from 1..n and the array is immutable. In my silly example with remove, a List would be more appropriate. Etc.
try
int i = Arrays.asList(arr).indexOf(obj);
As #Aaron_H said, no dice. I'll add that you can work around it with something like this:
public class Test {
public static void main(String[] args) {
ZenArray<IndexedString> z = new ZenArray(10);
for (int i = 0; i < z.size(); i++) {
z.set(i, new IndexedString("String " + i));
}
for (int i = 0; i < z.size(); i++) {
System.out.println("I'm at index " + z.get(i).getIndex());
}
}
}
class ZenArray<T extends ZenArray.IndexedElement> {
private Object [] a;
interface IndexedElement {
void setIndex(int i);
int getIndex();
}
public ZenArray(int size) {
a = new Object[size];
}
public void set(int i, T val) {
val.setIndex(i);
a[i] = val;
}
public T get(int i) {
return (T)a[i];
}
public int size() {
return a.length;
}
}
// An example of an indexed element implementation.
class IndexedString implements ZenArray.IndexedElement {
int i;
String val;
public IndexedString(String val) {
this.val = val;
}
public String getVal() {
return val;
}
#Override
public void setIndex(int i) {
this.i = i;
}
#Override
public int getIndex() {
return i;
}
}
I know that this question might have been asked before, but I was not able to find a fit answer. So say I have this array:
String[][] theArray = {
{"james", "30.0"},
{"joyce", "35.0"},
{"frank", "3.0"},
{"zach", "34.0"}};
Is there a way to descendingly sort this array by the second element of each sub-element. So I would get something like this.
theArray = {
{"joyce", "35.0"},
{"zach", "34.0"},
{"james", "30.0"},
{"frank", "3.0"}};
Use Arrays.sort(arr, comparator) with a custom comparator:
Arrays.sort(theArray, new Comparator<String[]>(){
#Override
public int compare(final String[] first, final String[] second){
// here you should usually check that first and second
// a) are not null and b) have at least two items
// updated after comments: comparing Double, not Strings
// makes more sense, thanks Bart Kiers
return Double.valueOf(second[1]).compareTo(
Double.valueOf(first[1])
);
}
});
System.out.println(Arrays.deepToString(theArray));
Output:
[[joyce, 35.0], [zach, 34.0], [james, 30.0], [frank, 23.0]]
Beware:
you will be sorting the array you passed in, Arrays.sort() will not return a new array (in fact it returns void). If you want a sorted copy, do this:
String[][] theCopy = Arrays.copyOf(theArray, theArray.length);
And perform the sorting on theCopy, not theArray.
You must use the Arrays.sort() method. This method takes a Comparator as argument. The sort method delegates to the comparator to determine if one element of the array must be considered bigger, smaller or equal to another element. Since every element of the outer array is an array, the comparator will have to compare arrays (of Strings).
The arrays must be compared based on the value of their second element. This second element is a String which in fact represents a double number. So you'll have to transorm the strings into numbers, else the order will be lexicographical (20 come before 3) rather than numerical.
The comparator could thus look like this :
public class StrinArrayComparator implements Comparator<String[]> {
#Override
public int compare(String[] array1, String[] array2) {
// get the second element of each array, andtransform it into a Double
Double d1 = Double.valueOf(array1.[1]);
Double d2 = Double.valueOf(array2.[1]);
// since you want a descending order, you need to negate the
// comparison of the double
return -d1.compareTo(d2);
// or : return d2.compareTo(d1);
}
}
If you want to move away from arrays, here's a variation that uses List<Record> and a RecordComparator that implements Comparator<Record>.
Console:
joyce 35.0
zach 34.0
james 30.0
frank 23.0
Code:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/** #see http://stackoverflow.com/questions/5064027 */
public class ComparatorTest {
public static void main(String[] args) {
List<Record> list = new ArrayList<Record>(Arrays.asList(
new Record("james", "30.0"),
new Record("joyce", "35.0"),
new Record("frank", "23.0"),
new Record("zach", "34.0")));
print(list, Sort.DESCENDING, Field.D);
}
private static void print(List<Record> list, Sort s, Field f) {
RecordComparator rc = new RecordComparator(s, f);
Collections.sort(list, rc);
for (Record r : list) {
System.out.println(r);
}
}
}
class Record {
private String s;
private Double d;
public Record(String name, String number) {
this.s = name;
this.d = Double.valueOf(number);
}
#Override
public String toString() {
return s + " " + d;
}
public int compareTo(Field field, Record record) {
switch (field) {
case S: return this.s.compareTo(record.s);
case D: return this.d.compareTo(record.d);
default: throw new IllegalArgumentException(
"Unable to sort Records by " + field.getType());
}
}
}
enum Sort { ASCENDING, DESCENDING; }
enum Field {
S(String.class), D(Double.class);
private Class type;
Field(Class<? extends Comparable> type) {
this.type = type;
}
public Class getType() {
return type;
}
}
class RecordComparator implements Comparator<Record> {
private Field field;
private Sort sort;
public RecordComparator(Sort sort, Field field) {
this.sort = sort;
this.field = field;
}
#Override
public final int compare(Record a, Record b) {
int result = a.compareTo(field, b);
if (sort == Sort.ASCENDING) return result;
else return -result;
}
}
You seem to be living in object denial. Those inner arrays look a lot like information about a Person (with the name and some value, maybe a score).
What you'd want to do is to write a custom class to hold that information:
public class Person {
private final String name;
private final double score;
public Person(final String name, final double score) {
this.name=name;
this.score=score;
}
public String getName() {
return name;
}
public double getScore() {
return score;
}
}
Then, when you want to sort them, you simply implement a Comparator<Person> that specifies how you want them sorted:
public PersonScoreComparator implements Comparator<Person> {
public int compare(Person p1, Person p2) {
return Double.compare(p1.getScore(), p2.getScore());
}
}
Alternatively, you could have the Person class itself implement Comparable<Person> by adding this method:
public int compareTo(Person other) {
return Double.compare(getScore(), other.getScore());
}
-Create list out of this array using Arrays.toList()
-Design comparator using java.lang.comparator and write logic for sorting every even elements
There are several sort methods in java.util.Arrays. Two of them take custom Comparators. Simply provide a comparator comparing the second element of the inner arrays.
public static void main(String[] args)
{
String Name[][]={{"prakash","kumar"},{"raj","kappor"},{"vinod","bhart"}};
String str[]=new String[2];
for(int j=0; j<Name.length;j++)
{
for (int i=0 ; i<2; i++)
{
str[i]=Name[j][i];
}
for(int i=0;i<str.length;i++)
{
for(int k=i+1;k<str.length;k++)
{
if(str[i].compareTo(str[k])>0)
{
String temp= str[i];
str[i]=str[k];
str[k]=temp;
}
}
System.out.print(str[i]+ " ");
}
System.out.println();
}
}
}
/**
*
* #param array - 2D array required to be arranged by certain column
* #param columnIndex - starts from 0; this will be the main comparator
* #param hasHeaders - true/false; true - ignore the first row. False -
* first row it's also compared and arranged
* #return - the new arranged array
*/
private String[][] arrangeArray(String[][] array, int columnIndex, boolean hasHeaders) {
int headersExists = 0;
if (hasHeaders) {
headersExists = 1;
}
for (int i = headersExists; i < array.length; i++) {
for (int j = headersExists; j < array.length; j++) {
if (array[i][columnIndex].compareTo(array[j][columnIndex]) < 0){
String[] temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
}
return array;
}