This question already has answers here:
How to override toString() properly in Java?
(15 answers)
How do I print my Java object without getting "SomeType#2f92e0f4"?
(13 answers)
Closed 2 years ago.
I am trying to write an function incrList(L, x) that copies a given Linear Linked List, L, recursively and increment by a constant value, x. When I compile in terminal I got IntList#6ff3c5b5, which is a memory location, instead of the actual list. I only want to change the function incrList itself to give the right output.
public class IntList {
public int first;
public IntList rest;
public IntList(int f, IntList r) {
first = f;
rest = r;
}
}
public class Lists1Exercises{
public static IntList incrList(IntList L, int x) {
if (L == null){
return null;
}else {
IntList head = new IntList(L.first+x, null);
head.rest = incrList(L.rest, x);
return head;
}
}
public static void main(String[] args) {
IntList L = new IntList(5, null);
L.rest = new IntList(7, null);
L.rest.rest = new IntList(9, null);
System.out.println(incrList(L, 3));
}
}
You need to override the toString method in your intlist class or write a method to convert from intlists to strings. You are returning an object, and by default they print as locations in memory.
public class IntList {
public int first;
public IntList rest;
public IntList(int f, IntList r) {
first = f;
rest = r;
}
#override
public String toString() {
// or whatever you want to print
return "First: " + first + " | Rest: " + rest;
}
}
By default the .toString() returns a string consisting of the name of the class of which the object is an instance, the at-sign character `#', and the unsigned hexadecimal representation of the hash code of the object.
But you can change it using #override and return whatever you want (usually something meaningful).
Related
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.
This question already has answers here:
Java Pass Method as Parameter
(17 answers)
How to pass a function as a parameter in Java? [duplicate]
(8 answers)
Closed 3 years ago.
I have a class with bunch of methods. In another class, I need to write a method, that handles the input values. To that method, I want to pass the method of the class that I want to call. How can we do that with Java after 1.8?
There are similar questions already, but those usually assume that we can use an interface with a single method, therefore can use lambda expressions, etc.
class MyClass {
public Object myToString(String a) {
return new String(a);
}
public Object myToString(String a, String b) {
return new String(a + ", " + b);
}
public Object mySum(int a) {
return new Integer(a);
}
public Object mySum(int a, int b) {
return new Integer(a + b);
}
}
class Test {
public Object handleInputs(MyClass myClass, MethodAsParameter theMethod, List<Object> inputs) {
if (type of inputs are Strings) {
myClass.myToString(inputs.get(0));
} else if (.....) {
myClass.mySum(inputs.get(0));
}
}
}
Since Java 8 you can use method reference. Method references can be assigned to Function<A, B> functional interface variables and their subclasses.
For example, method with such signature:
class Test {
public static int DoSomething(String s) {...}
}
can be assigned to a Function<String, Integer> variable like:
Function<String, Integer> method = Test::DoSomething;
and then called:
int result = method.apply("Hello!");
So with small improvements in your code, this is the way you can use your methods as method references and passed to other function as parameters.
class MyClass {
public static String myToString(String a, String b) {
return a + ", " + b;
}
//notice the boxing in here
public static int mySum(int a, int b) {
return a + b;
}
//not kind of an revolutionary function, just for demonstration
public static<T> T Invoke(BinaryOperator<T> bo, T o1, T o2) {
return bo.apply(o1, o2);
}
public static void main(String[] args) {
int sum = Invoke(MyClass::mySum, 10, 20);
String str = Invoke(MyClass::myToString, "a", "b");
System.out.println(sum);
System.out.println(str);
}
}
I think something like this is as far as you would get:
import java.util.List;
import java.util.Arrays;
import java.util.function.Function;
import java.util.function.BiFunction;
class MyClass {
public Object myToString(String a) {
return new String(a);
}
public Object myToString(String a, String b) {
return new String(a + ", " + b);
}
public Object mySum(int a) {
return Integer.valueOf(a);
}
public Object mySum(int a, int b) {
return Integer.valueOf(a + b);
}
}
public class MethodParams {
public static Object handleInputs(Function<Object,Object> method, List<Object> inputs) {
return method.apply(inputs.get(0));
}
public static Object handleInputs(BiFunction<Object,Object,Object> method, List<Object> inputs) {
return method.apply(inputs.get(0), inputs.get(1));
}
public static void main(String args[]) {
MyClass mc = new MyClass();
String str = (String)handleInputs((a) -> mc.myToString((String)a), Arrays.asList("string"));
System.out.println(str); // string
Integer sum = (Integer)handleInputs((a) -> mc.mySum((int)a), Arrays.asList(1));
System.out.println(sum); // 1
Integer sum2 = (Integer)handleInputs((a,b) -> mc.mySum((int)a, (int)b), Arrays.asList(1, 2));
System.out.println(sum2); // 3
}
}
Not very nice, but at least you have some leeway as to which method you want to use. Code as demonstrated here has lots of casts due to using Objects - using generic types as demonstrated by t2dohx is better way of doing this, but even further from your question.
Here is a simple example:
public class TestMain {
public static void main(String [] args) {
Long a = 15L, b = 20L;
Long sum = combineTwoNumbers(a, b, (p1, p2) -> p1 + p2);
Long product = combineTwoNumbers(a, b, (p1, p2) -> p1 * p2);
System.out.println("Sum is " + sum);
System.out.println("Product is " + product);
}
public static Long combineTwoNumbers(Long a, Long b, BiFunction <Long, Long, Long> combiner) {
return combiner.apply(a, b);
}
}
Here, the functional parameter is BiFunction, which takes two parameters in input and returns an output. Specifically, it takes two long numbers and produces a third one as a result. The name of the method is kept generic so that it can cover more instances of different functions that may take place. In our example we are passing a sum and a product function as you can see.
This question already has answers here:
Comparing string to array string and binary searching
(2 answers)
Closed 5 years ago.
I have following interface:
public interface Generator <T> {
public T next ();}
and the class that has several methods and fields. I will write my code in order so you will understand my probem.
Class:
public class Example implements Comparable <Example>{}
This class has fields like:
private String name;
private static int count;
private int ID = count ++;
private static char [] chars = "qwertyuiopasdfghjklzxcvbnm".toCharArray();
Constructor:
public Example (String name){
this.name = name;
}
Method that returns information about class:
public String toString (){
return "ID #" + ID + ", name: " + name;
}
Method that produces new classes:
public static Generator <Example> generator (){
return new Generator <Example> (){
public Example next() {
Random rand = new Random ();
StringBuilder str = new StringBuilder ();
for (int i=0; i!=10; i++)
str.append(chars[rand.nextInt(chars.length)]);
return new Example (str.toString());
}
};
}
and this incomprehensible method that I can not understand:
public int compareTo(Example o) {
return (this.name < o.name ? -1 : (this.name == o.name ? 0 : 1)); // It does not works... :(
}
Generic method that produces array:
public static <T> List <T> array (List <T> list, Generator <T> gen, int size){
for (int i=0; i!=size; i++){
list.add(gen.next());
} return list;
}
and main method when I am trying to compare sort array:
public static void main (String [] args){
List <Example> list = new ArrayList <Example> (); // Created the array;
array (list, generator(), 10); // Filled the array;
Collections.sort(list); // Doesn't work :(
}
I'm sorry for my English. English is not my native language.
Thank you :)
return (this.name < o.name ? -1 : (this.name == o.name ? 0 : 1)); // It does not works... :(
in your compareTo() implementation you are comparing String with < operator which is invalid. you can do it like
return this.name.compareTo(o.name); // for natural string comparison
This question already has answers here:
How do I use Comparator to define a custom sort order?
(9 answers)
Closed 7 years ago.
I am struggling sorting an array in order of an object's property. I know how to sort numbers in order, but I can't figure out how to do it with an object. For example, let's say object A has a position attribute of 1 and object B has a position attribute of 2. These objects are in an array. How could I sort them according to this property?
Thanks
You have something like:
public class ExampleObject {
public int position;
}
Then, simply use a Comparator.
public static void main(String args[]) {
//example numbers
final Random r = new Random();
final List<ExampleObject> arrList = new ArrayList<>(100);
for (int i = 0; i < 100; i++) {
ExampleObject obj = new ExampleObject();
obj.position = r.nextInt(1000);
arrList.add(obj);
}
//comparator (as a lambda)
Collections.sort(arrList, (a, b) -> {
return a.position - b.position;
});
//output result
for (ExampleObject obj : arrList) {
System.out.println(obj.position);
}
}
Also, in case you must sort an array and not a List, you can use Arrays.sort() with a Comparator like this as well.
You can compare by implementing Comparable interface in your class like below.
public class Applcation {
public static void main(String[] args) {
A ary[] = {new A("D", 1),new A("C", 7),new A("K", 4),new A("L", 8),new A("S", 3)};
Arrays.sort(ary);
for (A a : ary) {
System.out.println(a.id+" - "+a.name);
}
}
}
class A implements Comparable<A>{
String name;
int id;
public A(String name, int id) {
this.name = name;
this.id = id;
}
#Override
public int compareTo(A a) {
return this.id-a.id;
}
}
Or as an alternative you can use java 8 streams to sort your array without implementing Comparable :
Arrays.stream(ary).sorted((a1,a2)->Integer.compare(a1.id, a2.id)).forEach(e->System.out.println(e.id+" - "+e.name));
Out-put :
1 - D
3 - S
4 - K
7 - C
8 - L
I am trying to take data from a text file containing Strings and Integers into an ArrayList, and then sort it (which will depend on the integer values).
The text in the file pattern looks like this "Höllviken;23642". Seperated by a ";" character.
So far I've gotten this:
public class SorteraOrter{
public static void main(String[] args)throws IOException{
// scans file orter
File stad = new File("C:\\Users\\Johan\\Desktop\\orter.txt");
Scanner n = new Scanner(stad);
ArrayList<Object> city = new ArrayList();
while(n.hasNext()){
String ln = n.nextLine();
String[] arr = ln.split(";");
Ort ort = new Ort(arr[0],Integer.valueOf(arr[1]));
city.add(ort);
}
System.out.println(city.toString());
}
}
For sorting i have declared some methods and made a compareTo method to use with sort.
:
package soter_orter;
public class Ort implements Comparable<Ort> {
// fields
private int postnr = 0;
private String ort = "";
// constructor
public Ort(String s, int p){s = ort; p = postnr;}
// method names
public int postnr() {
return postnr;
}
public String ort() {
return ort;
}
public int compareTo(Ort o){
return o.postnr - postnr;
}
public String toString(){
return ort + " " + postnr;
}
}
So to do this first i have to succeed in adding these Strings and Integers into my ArrayList. I also need to have them connected in some way since the number and the text file belong to eachother.
My current problem is the output im getting after trying to move the file-input to the ArrayList -
[ 0, 0, 0, 0, 0, 0, 0]
I've come a bit further and added the elemets of my ArrayList to an Object Array. I am able to sort this but unable to view it using my toString method.
Object[] arr = new Object[city.size()];
for (int i = 0; i<city.size(); i++){
arr[i] = city.get(i);
}
Arrays.sort(arr);
for (Ort o : arr){
}
I am unable to print this in the for loop. I get the message: "Type mismatch: cannot convert from element type Object to Ort"
So, so far I am unable to print the ArrayList neither the Object Array.
your constructor in Ort class should be
public Ort(String s, int p){ort=s; postnr=p;}
Your constructor ir wrong.
replace
public Ort(String s, int p){s = ort; p = postnr;}
for
public Ort(String s, int p){ort = s; postnr = p;}