I have this Test class and I have to write the others classes code in order to pass the asserts.
That's the Test class:
import java.util.*;
public class Test
{
public static void main(String[] args)
{
Book javabook = new Book("Learn Java",150);
Book cbook = new Book("C",120);
Book[] books = new Book[] {javabook, cbook};
Library lib = new Library(books);
assert(lib.pages() == 270);
List l = lib;
assert(l.size() == 2);
Collections.sort(l);
assert(l.get(0) == cbook);
assert(l.get(1) == javabook);
}
}
I started making the Book class, here is my implementation:
public class Book implements Comparable
{
private String name;
private int pages;
public Book(String name, int pages)
{
this.name = name;
this.pages = pages;
}
public int getPages()
{
return this.pages;
}
public int compareTo(Object obj)
{
if(this == obj) return 0;
else
{
Book x = (Book) obj;
return this.pages - x.pages;
}
}
}
Then I wrote the Library class:
import java.util.*;
public class Library extends ArrayList
{
ArrayList a;
public Library(Book[] b)
{
a = new ArrayList(b.length);
for(int i=0; i<b.length; i++)
{
a.add(b[i]);
}
}
public int pages()
{
int p = 0;
for(int i=0; i<a.size(); i++)
{
p += ( (Book) a.get(i) ).getPages();
}
return p;
}
public int size()
{
return a.size();
}
public Object get(int i)
{
return a.get(i);
}
}
I think the problem is on the Library class, seems like the Collections.sort doesn't work and I can't pass the asserts after the call of the method sort in the Test class! I can't figure out what's the problem on my code, can someone help me please?
Remember: I have to make my code in order to pass the asserts.
I'm not sure about my Library implementation in order to make this line on the Test work:
List l = lib;
Not sure about the ArrayList extension.
P.S. I know it's better to use generic types but I mustn't use them for this exercise. Without using them I get some warnings, just ignore them.
Your implementation of the Library class is indeed wrong - it shouldn't have a list of Books, it should be a list of Books - that's why it extends an ArrayList:
public class Library extends ArrayList<Book> {
// Note: no additional data members.
// The Library is already a List<Book>:
public Library(Book[] b) {
super(Arrays.asList(b));
}
public int pages() {
int p = 0;
for(int i = 0; i < size(); i++) {
p += get(i).getPages();
}
return p;
}
}
Related
Say I have a simple class like this:
public class BasicObject {
private String name;
public BasicObject (String str) {
name = str;
}
public String getName () {
return name;
}
}
then I have some simple method in the main class like this:
private static int findInList (____ list, String str) {
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getName().equalsIgnoreCase(str)) {
return i;
}
}
return -1;
}
It would work if I put List<BasicObject> on the blank for the parameter list, but what if I have other objects? Can I generalize the list so this would work with other objects besides BasicObject? If so, how can I get the type of the objects in the list?
Edit: What if I have another class from an imported package that I can still put in a list but I don't want to change what it implements? Is there a way to have a generalized findInList that includes those too? Or do I have to just make another method for that? I'm fine with just making another method, but I'm curious if this way is possible.
You can use an interface structure such as this
Doing so provides a common call structure, so it is predictable what can be called from the implementations
public interface IShape {
String getName();
}
public class Square implements IShape {
private String name = "Square";
#Override
public String getName() {
return name;
}
}
public class Circle implements IShape {
private String name = "Circle";
#Override
public String getName() {
return name;
}
}
public static void main(String[] args){
List<IShape> list = new ArrayList<>();
list.add(new Square());
list.add(new Circle());
list.add(new Circle());
list.add(new Square());
list.add(new IShape() {
#Override
public String getName() {
return "Triangle";
}
});
for(IShape test : list){
System.out.println(test.getName());
}
}
this produces an output like this
Square
Circle
Circle
Square
Triangle
as answer to edit
Yes, but requires reflection, if help is needed on this, please open a new question after proberly trying to solve the issue yourself.
Have you tried checking generics? It is what you're looking for, your method signature should look like below:
public <T> List<T> findInList (Class<T> list, String str) {}
This will work if all objects have common parent (BasicObject or any other class which have getName() method).
private static int findInList (List<? extends BasicObject> list, String str) {
for (int i = 0; i < list.size(); i++) {
if (list.get(i).getName().equalsIgnoreCase(str)) {
return i;
}
}
return -1;
}
Your code relies on the list having an element type with a getName method that is visible to the compiler. Another way is to use lambdas. For example,
public interface Named {
String getName();
}
public class UseNamed<T extends Named> {
public int findIndex(List<T> nameds, String search) {
for (int len = nameds.size(), ix = 0; ix < len; ++ix) {
final Named named = names.get(ix);
if (search.equalsIgnoreCase(named.getName())) {
return ix;
}
}
return -1;
}
One approach with lambdas is to pass a comparer to findIndex:
public <T, K> int findIndex(List<T> stuff, K search,
BiFunction<T, K, Boolean> compares) {...}
and call it with
List<Named> stuff = ...;
String search = ...;
int index = findIndex(stuff, search,
(named, s) -> s.equalsIgnoreCase(named.getName()));
I am trying to fill UCFCourse courseOne in my constructor with a courses[] object in fillWithCourses().UCFCourse courseOne does populate outside of the constructor but will not go into it.
public class UCFSemester<courses> {
private static UCFCourse courseOne;
private static double totalSemesters;
private static double completionTime;
static boolean fillSemester = true;
public UCFSemester(UCFCourse courseOne, UCFCourse[] coursetwo) {
this.courseOne = courseOne;
}
public static UCFCourse getcourseOne() {
return courseOne;
}
public static void setCoursesone(UCFCourse courses) {
courseOne = courses;
}
public static void fillWithCourses(UCFCourse courses[], int l) {
int x = 0;
while (fillSemester) {
for (int n = 0; n < 5; n++) {
if (x != n && courses[x].getCourseLevel() < courses[n].getCourseLevel()) {
setCoursesone(courses[x]);
}
}
fillSemester = false;
}
}
}
Side question.How can I access this all in a non-static way?I need the entire thing to be non-static but no matter what I do I can't get it.Thanks!
You can simply do it by creating a List like this:
public class UCFSemester {
private List<UCFCourse> courseList = new ArrayList<>();
public UCFCourse getCourse(int index) {
return courseList.get(index);
}
public void addCourses(UCFCourse[] courses) {
for(int x = 0; x < courses.length; x++) {
courseList.add(courses[x]);
}
}
}
Here, I'm assuming that you are passing the UCFCourse[] array with all the course details that are there in that particular semester.
addCourses() function will take this array and then add all the corresponding courses to the List.
getCourse() function will return you any particular course from the List (Using Index). You can also modify the search in any way you want.
I am working on some kind of software delivery tool. For one of its task the program needs to find the class file names which will generate after compiling any given java file.
I need some kind of parsing library/approach which can detect all inner
classes(named as well as anonymous) too.
e.g.: If input file contains below code. Our program should generate output as: SampleClass1.class, SampleClass1$Data.class, SampleClass1$1.class
package com.aci.uob.patchmanifest.helper.testapp;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
public class SampleClass1 {
public static String CONSTANT_ATTR = "Sample String Constant";
int attr;
boolean b;
private class Data implements Comparable<Data>{
String val="--";
public Data(String val) {
super();
this.val = val;
}
#Override
public int compareTo(Data o) {
return this.val.compareTo(o.val);
}
}
public SampleClass1(int attr, boolean b) {
super();
System.out.println("this is a sample constructor");
this.attr = attr;
this.b = b;
}
private void runInnerClasses(){
List<Data> list=new ArrayList<Data>();
list.add(new Data("Hello"));
list.add(new Data("World"));
list.add(new Data("20"));
list.add(new Data("100"));
list.add(new Data(" Hello"));
Collections.sort(list);
printList(list);
Collections.sort(list, new Comparator<Data>() {
#Override
public int compare(Data o1, Data o2) {
// TODO Auto-generated method stub
return o1.val.trim().compareToIgnoreCase(o2.val.trim());
}
});
}
private void printList(List<Data> list) {
for(Data d: list)
System.out.println(d.val);
}
}
If your program are running under Eclipse, JDT API(org.eclipse.jdt.core plugin) is a choice. Here is a example:
IJavaElement ele = JavaCore.create(ifile);
if (ele instanceof ICompilationUnit) {
IType[] czs = ((ICompilationUnit)ele).getAllTypes();
for (int i = 0; i < czs.length; i++) {
System.out.println(czs[i].getTypeQualifiedName());
//IType.getFullyQualifiedName() will return value include package name
IMethod[] ims = czs[i].getMethods();
for (int j = 0; j < ims.length; j++) {
IJavaElement[] childs = ims[j].getChildren();
//find anonymous type inside Method
for (int k = 0; k < childs.length; k++) {
if (childs[k] instanceof IType) {
System.err.println(((IType)childs[k]).getTypeQualifiedName());
}
}
}
}
}
Output example:
SampleClass1
SampleClass1$Data
SampleClass1$1
The JDT core API doesn't handle naming of anonymous types.
If private void printList(List list) also include a anonymous type.
The API also return SampleClass1$1.
You may also need czs[i].getFields() to find anonymous type inside Field. If SampleClass1 declare a class variable like:
Runnable r = new Runnable() {
public void run(){};
};
I tried looking up tutorials and videos and I understand what implementing does, although I'm a bit confused as to how one would implement a class from the Java Library. In my homework, I'm suppose to utilize the class, DataSet and make it so it accepts Comparable objects. The program is suppose to record the Min and Max values depending on the objects, in this case, I'm suppose to use strings. I wasn't sure if I needed any classes to implement the Comparable interface, so I made two classes just in case I was suppose to do so. My real question is how do I actually incorperate a String variable in the tester class to actually read and compare the object to another? thanks in advance.
public class Word implements Comparable
{
private String str;
public Word()
{
str = null;
}
public Word(String s)
{
str = s;
}
public int compareTo(Object other)
{
String n = (String) other;
return str.compareTo(n);
}
}
I wasn't sure which of the two classes would be suitable for implementing Although i think the String class below would not work at all b/c It's already a standard class so I wasn't too sure about using it
public class String implements Comparable
{
public String s;
public String()
{
s = null;
}
public String(String str)
{
s = str;
}
public int compareTo(Object other)
{
String n = (String) other;
return s.compareTo(n);
}
}
public interface Comparable
{
public int compareTo(Object other);
}
public class DataSet
{
private Object maximum;
private Object least;
private Comparable compare;
private int count;
public DataSet(Comparable s)
{
compare = s;
}
public void add(Object x)
{
if(count == 0)
least = x;
if(count == 0 || compare.compareTo(x) >=0)
maximum = x;
else if(compare.compareTo(x) <0)
least = x;
count++;
}
public Object getMaximum()
{
return maximum;
}
public Object getLeast()
{
return least;
}
}
public class DataSetTester
{
public static void main(String[] args)
{
Comparable n = new Word("sand");
DataSet data = new DataSet(n);
data.add(new Word(man));
System.out.println("Maximum Word: " + data.getMaximum());
System.out.println("Least Word: " + data.getLeast());
}
}
An interface is a contract that showes that your class contain all methodes that are implemented in the interface. In this case the CompareTo(object other). The String class already implements the comparable interface so you don't need youre own class. I think your data set class should look something like this :
public class DataSet<T implements Comparable>
{
private T maximum;
private T least;
private T count;
public void add(T x)
{
if(count == 0){
least = x;
maximum = x;
}
else if(least.compareTo(x) > 0)
least = x;
else if(maximum.compareTo(x) < 0)
maximum = x;
count++;
}
public T getMaximum()
{
return maximum;
}
public T getLeast()
{
return least;
}
}
T is a generic type and in your case it should be String, Here is how you create a new Data set:
DataSet<String> ds = new DataSet<String>;
I have the following code for sorting. Can this be improved?
import java.util.*;
class Church {
private String name;
private String pastor;
public Church(String name, String pastor) {
this.name = name;
this.pastor = pastor;
}
public String getPastor() {
return pastor;
}
public String getName() {
return name;
}
public void setPastor(String pastor) {
this.pastor = pastor;
}
public String toString() {
return getName() + " is Pastored by "+getPastor();
}
public int compareByPastor(Church c) {
int x = pastor.compareTo(c.getPastor());
return x;
}
public int compareByName(Church c) {
int x = name.compareTo(c.getName());
return x;
}
}
class Churches {
private final List<Church> churches;
public Churches() {
churches = new ArrayList<Church>();
}
public void addWithoutSorting(Church c) {
churches.add(c);
}
//You could always add using this method
public void addWithSorting(Church c) {
}
public void display() {
for(int j = 0; j < churches.size(); j++) {
System.out.print(churches.get(j).toString());
System.out.println("");
}
}
public List<Church> getChurches() {
return churches;
}
public void sortBy(String s) {
for (int i = 1; i < churches.size(); i++) {
int j;
Church val = churches.get(i);
for (j = i-1; j > -1; j--) {
Church temp = churches.get(j);
if(s.equals("Pastor")) {
if (temp.compareByPastor(val) <= 0) {
break;
}
}
else if(s.equals("Name")) {
if (temp.compareByName(val) <= 0) {
break;
}
}
churches.set(j+1, temp);
}
churches.set(j+1, val);
}
}
public static void main(String[] args) {
Churches baptists = new Churches();
baptists.addWithoutSorting(new Church("Pac", "Pastor G"));
baptists.addWithoutSorting(new Church("New Life", "Tudor"));
baptists.addWithoutSorting(new Church("My Church", "r035198x"));
baptists.addWithoutSorting(new Church("AFM", "Cathy"));
System.out.println("**********************Before Sorting***********************");
baptists.display();
baptists.sortBy("Pastor");
System.out.println("**********************After sorting by Pastor**************");
baptists.display();
baptists.sortBy("Name");
System.out.println("**********************After sorting by Name****************");
baptists.display();
}
}
Take a look at Collections.sort(list, comparator)
http://download.oracle.com/javase/6/docs/api/java/util/Collections.html
class Churches
{
public void sortBy(String attribute)
{
Comparator<Church> c = null;
if ("Name".equals(attribute)) c = new ChurchNameComparator();
else if ("Pastor".equals(attribute)) c = new ChurchNameComparator();
else System.out.println("unexpected sort attribute : '" + attribute + "'");
if (c != null) Collections.sort(churches, c);
}
private static final class ChurchNameComparator implements Comparator<Church>
{
public int compare(Church c1, Church c2)
{
return c1.getName().compareTo(c2.getName());
}
}
private static final class ChurchPastorComparator implements Comparator<Church>
{
public int compare(Church c1, Church c2)
{
return c1.getPastor().compareTo(c2.getPastor());
}
}
}
The real answer here is pretty much in line with iluxa's: you want to implement a Comparator interface on your Church objects (sample code here, though you'll want to decide what constitutes greater than/less than for a church...), and then you can use Collections.sort() to sort them. That will get the job done, at the end of the day.
Of course, you just asked for advice about sorting on Stack Overflow, so I feel compelled to ask you if you need an in-place sort, what kind of Big-O performance you're looking for, and then ask you to choose between Quicksort, IntroSort, HeapSort, MergeSort, and StoogeSort for what will work best for you.
For kicks, I once coded up a few sorts in Java:
This one forces Quicksort into quadratic time, which was harder to do than I'd originally assumed,
This one shows how to implement MergeSort,
and this one demonstrates a HeapSort
I did these for my own enjoyment and education. As a general rule, you want to stick with the standard library for these sorts of things.